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

From: Ruslan Ermilov <ru_at_FreeBSD.org>
Date: Fri, 13 Aug 2004 09:15:31 +0300
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

Received on Fri Aug 13 2004 - 04:15:35 UTC

This archive was generated by hypermail 2.4.0 : Wed May 19 2021 - 11:38:06 UTC