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