tech-toolchain archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: worrying differences in object code due to different build host!



At Thu, 14 May 2015 20:17:09 -0400, Andrew Cagney <andrew.cagney%gmail.com@localhost> wrote:
Subject: Re: worrying differences in object code due to different build host!
> 
> Did the size or alignment of "struct ibcs2_dirent idb" change?
>

Well, the alignment may have (there are no changes in any data or bss
symbols, so I don't expect its size to have changed), I don't think it
should have, but that does appear to explain the particular diff I
showed.  An alignment difference shouldn't affect the execution though,
I don't think.  Unfortunately there's no global object of that type so
one doesn't appear in the final symbol table for quick comparison.

An alignment difference might also be easier to explain when the
toolchain runs on different hosts -- that kind of bug seems like it
might be easier to slip through since it wouldn't cause any obvious
problems in code execution unless perhaps objects built on different
hosts were mixed.

However that is only the simplest diff in the assembly code and some of
the others seem to me to suggest quite different instruction sequences
were generated on the different build hosts.

So I spent a whole bunch of time hacking on and rewriting a script
(originally posted by Eric Haszlakiewicz) to compare two binaries based
on their symbol tables, and here's the result of comparing an OLD kernel
built on an old netbsd-4/i386 box (called "once") with a NEW kernel
built on a new netbsd-5/amd64 box (called "building") (with the same
sources, there was no change in the source tree in the intervening month
-- it just took me that long to go and do the build on the old machine
and then to poke about again at the result).

Unfortunately this i386-built i386 kernel won't boot in a domU either,
so perhaps chasing up toolchain differences isn't the most immediate
concern for my Xen problems.  Perhaps I need to chase it down from the
Xen side first to see what, if any, kernel code might be responsible.
(though the change in xen_bootstrap_tables is curious)

Anyway, here's the results and the new script is attached for reference.
(there still appears to be an off-by-one error in there, perhaps in how
I sum identical local symbols together, but I can't find or explain it)

I can post more interesting diffs if anyone would like to see them, or
I can even make all the assembler files available for anyone to download.

OLD: /netbsd-5.2_STABLE-i386-XEN3PAE_DOMU-once
        NetBSD 5.2_STABLE (XEN3PAE_DOMU) #0: Sat May 23 10:40:09 PDT 2015
NEW: /netbsd-5.2_STABLE-i386-XEN3PAE_DOMU-building
        NetBSD 5.2_STABLE (XEN3PAE_DOMU) #7: Sun Apr 26 23:52:20 PDT 2015

                        Old             New | +        Size
   Section             Size            Size | -       delta
   -------             ----            ---- |         -----
      text          3084364         3083564 | -         800
      data            65924           65924 | -           0
    rodata           426115          423211 | -        2904
       bss           470484          470484 | -           0
   -------             ----            ---- |         -----
     Total          4178406         4174630 | -        3776
   -------             ----            ---- |         -----
     Nsyms            12756           12756 | -           0

Symbols changed in size between OLD: /netbsd-5.2_STABLE-i386-XEN3PAE_DOMU-once
                            and NEW: /netbsd-5.2_STABLE-i386-XEN3PAE_DOMU-building:

Type Symbol                           Old Size   New Size    Delta
---- ------                           --------   --------    -----
T    bios32_init                           732        693      -39
T    bstp_initialization                   677        663      -14
T    bstp_input                           1253       1225      -28
T    calcru                               1208       1206       -2
T    cpu_startup                           741        740       -1
T    db_write_bytes                        712        696      -16
t    dump_seg_iter                         498        442      -56
t    ffs_indirtrunc                       1627       1784      157
T    ffs_snapremove                       1701       1669      -32
T    ffs_snapshot                         7199       7203        4
T    ffs_truncate                         7048       7133       85
t    filt_irframetread                      52         42      -10
T    gdt_init_cpu                          469        459      -10
t    get_system_time                       216        220        4
T    ifioctl_common                       1057       1047      -10
T    ip_output                            5079       5107       28
t    lfs_indirtrunc                       1639       1736       97
T    lfs_resize_fs                        2471       2487       16
T    lfs_vfree                            5443       5194     -249
T    namei                                4085       4092        7
T    nfs_cookieheuristic                   407        401       -6
T    nfs_loadattrcache                    1518       1502      -16
T    nfs_readdirplusrpc                   3739       3685      -54
T    nfs_readdirrpc                       3292       3244      -48
T    nfsrv_create                         6402       6400       -2
T    nfsrv_fsinfo                         1689       1690        1
T    nfsrv_mkdir                          4618       4616       -2
T    nfsrv_mknod                          4770       4763       -7
T    nfsrv_setattr                        4392       4384       -8
T    nfsrv_statfs                         2125       2127        2
T    nfsrv_symlink                        4590       4583       -7
T    nfsrv_writegather                    4601       4585      -16
t    pmap_do_remove                       3719       3657      -62
T    pmap_enter_ma                        4100       4092       -8
T    pmap_extract                          489        454      -35
T    pmap_kenter_ma                        290        274      -16
T    pmap_kenter_pa                        453        423      -30
T    pmap_kremove                          415        393      -22
T    pmap_map                              177        148      -29
T    pmap_pdp_dtor                         372        362      -10
T    pmap_tlb_shootdown                    428        412      -16
T    pollcommon                           1421       1366      -55
T    pps_event                             499        502        3
T    ptyfs_readdir                         952        953        1
T    sb_max_set                            107        111        4
T    svr4_sys_llseek                       100         83      -17
t    swstrategy                           1021       1015       -6
T    sys_swapctl                          3144       3146        2
t    sysctl_hw_setup                      1735       1737        2
t    tc_windup                             753        769       16
T    ufs_bmaparray                        2665       2698       33
T    ufs_vinit                             188        186       -2
T    union_statvfs                         377        373       -4
T    uobj_unwirepages                      325        284      -41
T    update_descriptor                     219        212       -7
T    uvn_findpages                         265        268        3
t    vndthread                            1925       1941       16
t    wapbl_log_position                   4498       4391     -107
t    xen_bootstrap_tables                 1747       1585     -162
T    xen_set_ldt                           361        351      -10
t    xen_timer_handler                     450        446       -4
t    xennet_xenbus_detach                 1157       1173       16

        .text absolute delta: -779
        other absolute delta: 0

-- 
						Greg A. Woods
						Planix, Inc.

<woods%planix.com@localhost>       +1 250 762-7675        http://www.planix.com/

#!/bin/sh
#
# Usage: objsizecmp.sh OLDKERN NEWKERN

# original from http://www.nimenees.com/netbsd/ksize/gen.sh
# via a tech-kern post:
#
# Subject: Re: How to compare a kernel built with GCC 3.4.2 and GCC 4.0 (preliminary)
# To: Vincent <10.50%free.fr@localhost>
# From: Eric Haszlakiewicz <erh%jodi.nimenees.com@localhost>
# List: tech-kern
# Date: 11/09/2004 10:28:51

OKERN=${1:-/netbsd-}
NKERN=${2:-/netbsd}

# Label size
ls=10
# column size
cs=15
# diff column size
ds=12
printheader()
{
	printf "%${ls}.${ls}s  %${cs}.${cs}s %${cs}.${cs}s | %1s%${ds}.${ds}s\n" "${1}" "${2}" "${3}" "${5}" "${4}"
}
printnums()
{
	local vname nval oval mark
	# diff and xdiff are not local

	vname=${1}
	oval=${2}
	nval=${3}
	extra=${4}
	xdiff=$(($nval - $oval))
	if [ "$nval" -gt "$oval" ] ; then
		diff=$(($nval - $oval))
		mark="+"
	else
		diff=$(($oval - $nval))
		mark="-"
	fi
	printf "%${ls}.${ls}s  %${cs}d %${cs}d | %s%${ds}d%s\n" "$vname" $oval $nval "$mark" $diff $4
}

DIR=$(mktemp -dt $(basename $0))
if [ ! -d "$DIR" ] ; then
	echo "ERROR: '$DIR' doesn't exist!" 1>&2
	exit 1
fi

trap "RC=$?; rm -rf $DIR*; exit $RC" 0 1 2 3 15

bnok=${DIR}/old
bnnk=${DIR}/new

nkern_size=$(size -A $NKERN | awk '/^Total/ { print $2; } ')
nkern_text=$(size -A $NKERN | awk '/^\.text/ { print $2; } ')
nkern_data=$(size -A $NKERN |  awk '/^\.data/ { print $2; } ')
nkern_bss=$(size -A $NKERN | awk '/^\.bss/ { print $2; } ')

okern_size=$(size -A $OKERN | awk '/^Total/ { print $2; } ')
okern_text=$(size -A $OKERN | awk '/^\.text/ { print $2; } ')
okern_data=$(size -A $OKERN | awk '/^\.data/ { print $2; } ')
okern_bss=$(size -A $OKERN | awk '/^\.bss/ { print $2; } ')

nkern_rodata=$(size -A "$NKERN" |  awk '/^\.rodata\.str1.8/ { print $2; } ')
if [ ${nkern_rodata:-0} -le 0 ]; then
	nkern_rodata=$(size -A "$NKERN" |  awk '/^\.rodata/ { print $2; } ')
fi
okern_rodata=$(size -A "$OKERN" |  awk '/^\.rodata\.str1.8/ { print $2; } ')
if [ ${okern_rodata:-0} -le 0 ]; then
	okern_rodata=$(size -A "$OKERN" |  awk '/^\.rodata/ { print $2; } ')
fi

getsyms()
{
# best:
	nm -B -p -S -t d ${1} |
			awk 'NF == 4 && $3 ~ /[bBcCdDtT]/ {
			print $2 " " $3 " " $4;
		}' |
#
# extra sort
#	nm -B --size-sort -t d ${1} |
#
# outputs different values for the "type"
#	objdump -t ${1} |
#		awk '$4 == ".text" {
#			printf("%d %s %s\n", "0x" $5, $3, $6);
#		}' |
		sort -k 3,3 |
		awk 'BEGIN {
			lr[1] = 0;
			lr[2] = "";
			lr[3] = "";
		}
		{
			if (NR > 1 && lr[2] == $2 && lr[3] == $3) {
				#
				# just sum the sizes for consecutive
				# matching records (i.e. multiple
				# occurances of the same local
				# symbol), as otherwise join shows
				# alternating +/- values for each
				#
				lr[1] += $1;
			} else {
				if (NR > 1) {
					print lr[1] " " lr[2] " " lr[3];
				}
				lr[1] = $1;
				lr[2] = $2;
				lr[3] = $3;
			}
		}
		END {
			print lr[1] " " lr[2] " " lr[3];
		}' > ${2}.nm

	# just the names.... but all the names
	#
	nm -B ${1} | awk '{ print $3; }' > ${2}.syms
}

getsyms ${OKERN} ${bnok}
okern_nsyms=$(wc -l < ${bnok}.syms)
getsyms ${NKERN} ${bnnk}
nkern_nsyms=$(wc -l < ${bnnk}.syms)

printf "OLD: "
what $OKERN
printf "NEW: "
what $NKERN

echo

printheader ""        "Old"  "New"  " Size" "+"
printheader "Section" "Size" "Size" "delta" "-"
printheader "-------" "----" "----" "-----" ""
printnums "text" $okern_text $nkern_text
printnums "data" $okern_data $nkern_data
printnums "rodata" $okern_rodata $nkern_rodata
printnums "bss" $okern_bss $nkern_bss
printheader "-------" "----" "----" "-----" ""
printnums "Total" $okern_size $nkern_size
printheader "-------" "----" "----" "-----" ""
printnums "Nsyms" $okern_nsyms $nkern_nsyms

comm -13 ${bnnk}.syms ${bnok}.syms > ${bnok}.only
comm -23 ${bnnk}.syms ${bnok}.syms > ${bnnk}.only

if [ -s ${bnnk}.only -o -s  ${bnok}.only ]; then
	echo
	syms_added=$(wc -l < ${bnnk}.only)
	syms_removed=$(wc -l < ${bnok}.only)
	printheader "Symbols" "--Added--" "--Deleted--" "--Change--" ""
	printnums "Total:" $syms_added $syms_removed ""
fi

cat <<'__EOF__' > ${DIR}/fmt-only.awk
BEGIN {
	tsize = 0;
	printf("%-4s %40s %10s\n", "Type", "Symbol", "Size");
}
{
	printf("%-4s %40s %10d\n", $2, $3, $1);
	tsize += $1;
}
END {
	printf("\n\tTotal size: %d\n", tsize);
}
__EOF__

showonly()
{
	echo
	echo "Symbols only in ${1}:"
	echo "(note:  some local-only symbols may not appear)"
	echo
	join -o 1.1,2.2,2.3 -1 1 -2 3     ${2}.only ${2}.nm |
		awk -f ${DIR}/fmt-only.awk
}

# xxx make this an option flag...
verbose=true

if $verbose && [ -s ${bnok}.only ]; then
	showonly ${OKERN} ${bnok}
fi
if $verbose && [ -s ${bnnk}.only ]; then
	showonly ${NKERN} ${bnnk}
fi


# Identify size change in all common symbols.

echo
echo "Symbols changed in size between OLD: $OKERN"
echo "                            and NEW: $NKERN:"
echo

cat <<'__EOF__' > ${DIR}/fmt-diff.awk
#
# input is:  osize nsize type symbol
#
BEGIN {
	tsize = 0;
	osize = 0;
	hfmt = "%-4s %-30s %10s %10s %8s\n";
	# everything right-adjusted becomes an integer format
	# XXX this only works in GNU Awk:
	#dfmt = gensub(/%([0-9]*)s/, "%\\1d", "g", hfmt);
	dfmt = hfmt;
	gsub(/%10s/, "%10d", dfmt);
	gsub(/%8s/, "%8d", dfmt);
	printf(hfmt, "Type", "Symbol", "Old Size", "New Size", "Delta");
	printf(hfmt, "----", "------", "--------", "--------", "-----");
}
$1 != $2 {
	delta = $2 - $1;
	if ($3 ~ /[tT]/) {
		tsize += delta;
	} else {
		osize += delta;
	}
	printf(dfmt, $3, $4, $1, $2, delta);
}
END {
	printf("\n\t.text absolute delta: %d", tsize);
	printf("\n\tother absolute delta: %d\n", osize);
}
__EOF__

join -o 1.1,2.1,1.2,1.3 -1 3 -2 3 ${bnok}.nm ${bnnk}.nm |
	awk -f ${DIR}/fmt-diff.awk


Home | Main Index | Thread Index | Old Index