New ld(1) changed behavior (was: Re: bin/70392: NO_DYNAMICROOT + savecore -z dumps core)

Ruslan Ermilov ru at FreeBSD.org
Thu Aug 12 23:15:35 PDT 2004


On Thu, Aug 12, 2004 at 09:27:19PM -0500, Skip Ford wrote:
> 
> Statically linking savecore (NO_DYNAMICROOT) causes conflict:
> 
> /usr/bin/ld: Warning: size of symbol `compress' changed from 4 in savecore.o to 27 in /usr/lib/libz.a(compress.o)
> /usr/bin/ld: Warning: type of symbol `compress' changed from 1 to 2 in /usr/lib/libz.a(compress.o)
> 
> 'compress' is an integer in savecore.o and a function in compress.o.
> The resulting binary dumps core when run with compression (-z).
> 
> Not sure if the conflict is valid or a toolchain problem, but renaming
> the int works around the problem.
> 
Another option is to staticize this variable, but I'm not yet
sure if this new behavior of ld(1) is correct.  It doesn't
exhibit in 4.x, with the same situation regarding the "compress"
variable/function.  I was looking for a possible explanation of
why this could be happening, and I hope I found why, but I'd
need a confirmation from those more familiar with the linker
rules.  Here's the hopefully relevant information from ld.info:

    `int i;'
          A common symbol.  If there are only (one or more) common
          symbols for a variable, it goes in the uninitialized data
          area of the output file.  The linker merges multiple common
          symbols for the same variable into a single symbol.  If they
          are of different sizes, it picks the largest size.  The
          linker turns a common symbol into a declaration, if there is
          a definition of the same variable.

So if I interpret this correctly, it means that linker should
convert a common from savecore.o to a reference to "compress"
(a definition) from libz.a.  But in 4.x, when you statially
link savecore, it puts "compress" from savecore.o into the BSS
section:

: # make -DNOMAN -DNOSHARED
: Warning: Object directory not changed from original /usr/src/sbin/savecore
: cc -O -pipe     -c savecore.c
: cc -O -pipe      -static -o savecore savecore.o -lz
: # nm savecore.o /usr/lib/libz.a savecore |grep -w compress
: 00000004 C compress
: compress.o:
: 000000a0 T compress
: 081754e0 B compress

In 5.x, a linker does this (for the reference):

: # make -DNOMAN -DNOSHARED
: Warning: Object directory not changed from original /usr/src/sbin/savecore
: cc -O -pipe -march=pentiumpro -Wsystem-headers -Werror -Wall -Wno-format-y2k -W -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Wreturn-type -Wcast-qual -Wwrite-strings -Wswitch -Wshadow -Wcast-align -Wno-uninitialized -c savecore.c
: cc -O -pipe -march=pentiumpro -Wsystem-headers -Werror -Wall -Wno-format-y2k -W -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Wreturn-type -Wcast-qual -Wwrite-strings -Wswitch -Wshadow -Wcast-align -Wno-uninitialized  -static -o savecore savecore.o -lz
: /usr/bin/ld: Warning: size of symbol `compress' changed from 4 in savecore.o to 48 in /usr/lib/libz.a(compress.o)
: /usr/bin/ld: Warning: type of symbol `compress' changed from 1 to 2 in /usr/lib/libz.a(compress.o)
: # nm savecore.o /usr/lib/libz.a savecore |grep -w compress
: 00000004 C compress
: compress.o:
: 000000c0 T compress
: 08051d60 T compress

If my assumptions are correct, then certainly, staticizing the
"compress" (and other now common globals in savecore.c) would
be a right solution.  Rebuilding the world with -DNOSHARED
globally is also recommended, to find other possible problems.


Cheers,
-- 
Ruslan Ermilov
ru at FreeBSD.org
FreeBSD committer
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 187 bytes
Desc: not available
Url : http://lists.freebsd.org/pipermail/freebsd-current/attachments/20040813/3530924b/attachment.bin


More information about the freebsd-current mailing list