Discussion:
[GOLD] icf_safe_so_test
Alan Modra
2018-12-07 07:22:17 UTC
Permalink
This test fails on powerpc64le, with icf_safe_so_test.sh.log as
follows:
Safe Identical Code Folding did not fold foo_hidden and foo_internal
FAIL icf_safe_so_test.sh (exit status: 1)

icf_safe_so_test.map has

Discarded input sections
...
.text._Z10foo_hiddenv
0x0000000000000000 0x2c icf_safe_so_test.o
.text._Z12foo_internalv
0x0000000000000000 0x2c icf_safe_so_test.o
.text._ZL10foo_staticv
0x0000000000000000 0x2c icf_safe_so_test.o
...

showing that foo_hidden, foo_internal, and foo_static have indeed been
folded (into foo_prot).

grep foo icf_safe_so_test_1.stdout
000000000000077c t _Z10foo_hiddenv
000000000000077c t _Z12foo_internalv
00000000000007a8 T _Z8foo_globv
000000000000077c T _Z8foo_protv

shows that foo_static has been discarded (reasonable since it is a
local and its section has been discarded), and that foo_hidden,
foo_internal, and foo_prot all have the same value.

Yet the test shell script scans the map file and for each pair of
symbols tested apparently expects to find one kept section and one
discarded. That's broken.

So I went looking to see who had broken the test and found
commit 4d9aa1551545dd5365d35a0844d3b7a5a35d02f3
Author: Alan Modra <***@gmail.com>
Date: Tue Mar 12 22:46:19 2013 +0000

Oh.. Right, I added the map scanning for powerpc64 ELFv1. Presumably
the test only passed due to !is_symbol_present on most of the symbols.

This patch rewrites the map file scan to test that we keep only one of
the four sections containing foo_prot, foo_hidden, foo_internal, or
foo_static code. Tested and passes on powerpc64le-linux,
powerpc64-linux and x86_64-linx.

* testsuite/icf_safe_so_test.sh (check_fold): Rewrite to check
multiple symbols at once.
(arch_specific_safe_fold): Likewise, and call with the four foo*
symbols expected to fold.

diff --git a/gold/testsuite/icf_safe_so_test.sh b/gold/testsuite/icf_safe_so_test.sh
index 28600be561..5810fbecec 100755
--- a/gold/testsuite/icf_safe_so_test.sh
+++ b/gold/testsuite/icf_safe_so_test.sh
@@ -59,45 +59,51 @@ check_nofold()

check_fold()
{
- if ! is_symbol_present $1 $2
- then
- return 0
- fi
-
- if ! is_symbol_present $1 $3
- then
- return 0
- fi
-
+ map=$1
+ shift
+ num_syms=$#
+ save_IFS="$IFS"
+ IFS='|'
+ sym_patt="$*"
+ IFS="$save_IFS"
awk "
BEGIN { discard = 0; }
/^Discarded input/ { discard = 1; }
/^Memory map/ { discard = 0; }
-/.*\\.text\\..*($2|$3).*/ { act[discard] = act[discard] \" \" \$0; }
+/.*\\.text\\..*($sym_patt).*/ { act[discard] = act[discard] \" \" \$0; cnt[discard] = cnt[discard] + 1 }
END {
- # printf \"kept\" act[0] \"\\nfolded\" act[1] \"\\n\";
- if (length(act[0]) == 0 || length(act[1]) == 0)
+ printf \"kept\" act[0] \"\\nfolded\" act[1] \"\\n\";
+ if (cnt[0] != 1 || cnt[1] != $num_syms - 1)
{
- printf \"Safe Identical Code Folding did not fold $2 and $3\\n\"
+ printf \"Safe Identical Code Folding failed\\n\"
exit 1;
}
- }" $4
+ }" $map
}

arch_specific_safe_fold()
{
if grep -q -e "Intel 80386" -e "ARM" -e "PowerPC" $1;
then
- check_fold $2 $4 $5 $3
+ shift
+ shift
+ #echo check_fold $*
+ check_fold $*
else
- check_nofold $2 $4 $5
+ shift
+ nm_output=$1
+ shift
+ shift
+ while test $# -gt 1; do
+ sym1=$1
+ shift
+ for sym2 in $*; do
+ #echo check_nofold $nm_output $sym1 $sym2
+ check_nofold $nm_output $sym1 $sym2
+ done
+ done
fi
}

-arch_specific_safe_fold icf_safe_so_test_2.stdout icf_safe_so_test_1.stdout icf_safe_so_test.map "foo_prot" "foo_hidden"
-arch_specific_safe_fold icf_safe_so_test_2.stdout icf_safe_so_test_1.stdout icf_safe_so_test.map "foo_prot" "foo_internal"
-arch_specific_safe_fold icf_safe_so_test_2.stdout icf_safe_so_test_1.stdout icf_safe_so_test.map "foo_prot" "foo_static"
-arch_specific_safe_fold icf_safe_so_test_2.stdout icf_safe_so_test_1.stdout icf_safe_so_test.map "foo_hidden" "foo_internal"
-arch_specific_safe_fold icf_safe_so_test_2.stdout icf_safe_so_test_1.stdout icf_safe_so_test.map "foo_hidden" "foo_static"
-arch_specific_safe_fold icf_safe_so_test_2.stdout icf_safe_so_test_1.stdout icf_safe_so_test.map "foo_internal" "foo_static"
-check_nofold icf_safe_so_test_1.stdout "foo_glob" "bar_glob"
+arch_specific_safe_fold icf_safe_so_test_2.stdout icf_safe_so_test_1.stdout icf_safe_so_test.map foo_prot foo_hidden foo_internal foo_static
+check_nofold icf_safe_so_test_1.stdout foo_glob bar_glob
--
Alan Modra
Australia Development Lab, IBM
Cary Coutant
2018-12-07 17:36:33 UTC
Permalink
Post by Alan Modra
* testsuite/icf_safe_so_test.sh (check_fold): Rewrite to check
multiple symbols at once.
(arch_specific_safe_fold): Likewise, and call with the four foo*
symbols expected to fold.
In case you're not checking this in as obvious, OK with me.

-cary
H.J. Lu
2018-12-07 17:48:45 UTC
Permalink
Post by Cary Coutant
Post by Alan Modra
* testsuite/icf_safe_so_test.sh (check_fold): Rewrite to check
multiple symbols at once.
(arch_specific_safe_fold): Likewise, and call with the four foo*
symbols expected to fold.
In case you're not checking this in as obvious, OK with me.
Does it fix

https://sourceware.org/bugzilla/show_bug.cgi?id=21128
--
H.J.
Loading...