Home | History | Annotate | Download | only in ld-elfcomm
      1 # Expect script for common symbol tests
      2 #   Copyright (C) 2003-2016 Free Software Foundation, Inc.
      3 #
      4 # This file is part of the GNU Binutils.
      5 #
      6 # This program is free software; you can redistribute it and/or modify
      7 # it under the terms of the GNU General Public License as published by
      8 # the Free Software Foundation; either version 3 of the License, or
      9 # (at your option) any later version.
     10 #
     11 # This program is distributed in the hope that it will be useful,
     12 # but WITHOUT ANY WARRANTY; without even the implied warranty of
     13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     14 # GNU General Public License for more details.
     15 #
     16 # You should have received a copy of the GNU General Public License
     17 # along with this program; if not, write to the Free Software
     18 # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
     19 # MA 02110-1301, USA.
     20 #
     21 # Written by H.J. Lu (hjl (at) gnu.org)
     22 #
     23 
     24 # Make sure that ld correctly handles common symbols in ELF.
     25 
     26 # This test can only be run on ELF platforms.
     27 if ![is_elf_format] {
     28     return
     29 }
     30 
     31 # hpux assembly is weird
     32 if [istarget "hppa*-*-hpux*"] {
     33     return
     34 }
     35 
     36 proc test_sort_common {} {
     37     global exec_output
     38     global objdump
     39     global srcdir
     40     global subdir
     41     global as
     42     global ld
     43 
     44     set test "--sort-common (descending)"
     45 
     46     verbose "Check to see that --sort-common sorts in descending alignment"
     47 
     48     # We do not run the sort common tests for the DLX target because we know that the linker
     49     # will seg-fault.  The built-in DLX linker script requires that there be something in the
     50     # .text section and our sort-common.s file does not provide anything.
     51     if [istarget dlx-*-*] {
     52 	untested "$test"
     53 	return 0
     54     }
     55 
     56     if { ![ld_assemble $as $srcdir/$subdir/sort-common.s tmpdir/sort-common.o] } {
     57 	unresolved "$test"
     58 	return 0
     59     }
     60 
     61     if { ![ld_simple_link $ld tmpdir/sort-common.dx "--sort-common=descending tmpdir/sort-common.o"] } {
     62 	fail "$test"
     63 	return 0
     64     }
     65 
     66     send_log "$objdump --syms tmpdir/sort-common.dx | grep var | sort\n"
     67     set exec_output [run_host_cmd "$objdump" "--syms tmpdir/sort-common.dx | grep var | sort"]
     68 
     69     # Don't know why, but the CR ports fail this test.
     70     setup_xfail "cr16-*-*" "crx-*-*"
     71 
     72     # Note: The second regexp is for targets which put small commons in a .sbss
     73     #  section and large commons in a .bss section.
     74     if {   ![regexp ".*var_16.*var_8.*var_4.*var_2.*var_1.*" $exec_output]
     75         && ![regexp ".*sbss.*var_8.*var_4.*var_2.*var_1.*bss.*var_16.*" $exec_output] } {
     76 	fail $test
     77     } else {
     78 	pass $test
     79     }
     80 
     81     set test "--sort-common (ascending)"
     82 
     83     verbose "Check to see that --sort-common=ascending sorts in ascending alignment"
     84 
     85     if { ![ld_simple_link $ld tmpdir/sort-common.ax "--sort-common=ascending tmpdir/sort-common.o"] } {
     86 	fail "$test"
     87 	return 0
     88     }
     89 
     90     send_log "$objdump --syms tmpdir/sort-common.ax | grep var | sort\n"
     91     set exec_output [run_host_cmd "$objdump" "--syms tmpdir/sort-common.ax | grep var | sort"]
     92 
     93     if {![regexp ".*var_1.*var_2.*var_4.*var_8.*var_16.*" $exec_output]} {
     94 	fail $test
     95 	return 0
     96     }
     97 
     98     pass $test
     99     return 1
    100 }
    101 
    102 test_sort_common
    103 
    104 set test1	"size/aligment change of common symbols"
    105 set test1w1	"$test1 (warning 1)"
    106 set test1w2	"$test1 (warning 2)"
    107 set test1c1	"$test1 (change 1)"
    108 set test1c2	"$test1 (change 2)"
    109 
    110 if { ![is_remote host] && [which $CC] == 0 } {
    111     untested $test1w1
    112     untested $test1w2
    113     untested $test1c1
    114     untested $test1c2
    115     return
    116 }
    117 if { [istarget score-*-*] } {
    118     untested $test1w1
    119     untested $test1w2
    120     untested $test1c1
    121     untested $test1c2
    122     return
    123 }
    124 
    125 proc dump_common1 { testname } {
    126     global exec_output
    127     global READELF
    128 
    129     send_log "$READELF --syms tmpdir/common1.o | grep foo\n"
    130     set exec_output [run_host_cmd "$READELF" "--syms tmpdir/common1.o | grep foo"]
    131 
    132     if {   ![regexp "(\[ 	\]*)(\[0-9\]+):(\[ 	\]*)(\[0\]*)80(\[ 	\]+)4(\[ 	\]+)(COMMON|OBJECT)(\[ 	\]+)GLOBAL(\[ 	\]+)DEFAULT(\[ 	\]+)(PRC\\\[0xff03\\\]|COM|SCOM)(\[ 	\]+)_?foo2" $exec_output]
    133 	|| ![regexp "(\[ 	\]*)(\[0-9\]+):(\[ 	\]*)(\[0-9\]+)(\[ 	\]+)21(\[ 	\]+)OBJECT(\[ 	\]+)GLOBAL(\[ 	\]+)DEFAULT(\[ 	\]+)(\[0-9\]+)(\[ 	\]+)_?foo1" $exec_output] } {
    134 	verbose $exec_output
    135 	fail $testname
    136 	return 0
    137     }
    138 
    139     return 1
    140 }
    141 
    142 proc stt_common_test { options testname } {
    143     global exec_output
    144     global READELF
    145     global ld
    146 
    147     set options "$options tmpdir/common1c.o"
    148 
    149     if { ! [ld_simple_link $ld tmpdir/common.exe $options] } {
    150       unresolved $testname
    151       return 0
    152     }
    153 
    154     send_log "$READELF --syms tmpdir/common.exe | grep foo\n"
    155     set exec_output [run_host_cmd "$READELF" "--syms tmpdir/common.exe | grep foo"]
    156 
    157     if {![regexp { +[0-9a-f]+. +[0-9a-f]+ OBJECT + GLOBAL +DEFAULT +[0-9]+ _?foo2} $exec_output] } {
    158 	fail $testname
    159 	return 0
    160     }
    161 
    162     pass $testname
    163     return 1
    164 }
    165 
    166 if [istarget nios2*-*-*] {
    167     set CFLAGS "$CFLAGS -G0"
    168 }
    169 
    170 # Explicitly use "-fcommon" so that even if $CFLAGS includes
    171 # "-fno-common", these tests are compiled as expected.
    172 if {   ![ld_compile "$CC $CFLAGS -fcommon" $srcdir/$subdir/common1a.c tmpdir/common1a.o]
    173     || ![ld_compile "$CC $CFLAGS -fcommon" $srcdir/$subdir/common1b.c tmpdir/common1b.o]
    174     || ![ld_compile "$CC $CFLAGS -Wa,--elf-stt-common=yes -fcommon" $srcdir/$subdir/common1b.c tmpdir/common1c.o] } {
    175     unresolved $test1
    176     unresolved $test1
    177     return
    178 }
    179 
    180 global ld
    181 global link_output
    182 
    183 set options "-r tmpdir/common1a.o tmpdir/common1b.o"
    184 
    185 # SH64 targets needs an extra ld option for this test.
    186 if [istarget sh64*-*-*] {
    187     if [istarget sh64*l*-*-*] {
    188 	set options "-mshlelf32 $options"
    189     } else {
    190 	set options "-mshelf32 $options"
    191     }
    192 }
    193 
    194 if { [ld_simple_link $ld tmpdir/common1.o $options] } {
    195     unresolved $test1w1
    196     return
    197 }
    198 
    199 # This test fails on MIPS because the backend sets type_change_ok.
    200 # The size change warning is suppressed.  Same on hppa64.
    201 if {[istarget mips*-*-*] || [istarget hppa*64*-*-*]} {
    202     if { ![regexp "Warning: alignment (\[0-9\]+) of symbol \`_?foo1\' in tmpdir/common1b.o is smaller than 64 in tmpdir/common1a.o" $link_output] } {
    203         fail $test1w1
    204     } else {
    205         pass $test1w1
    206     }
    207 } else {
    208     if { ![regexp "Warning: alignment (\[0-9\]+) of symbol \`_?foo1\' in tmpdir/common1b.o is smaller than 64 in tmpdir/common1a.o" $link_output]
    209          || ![regexp "Warning: size of symbol \`_?foo1\' changed from 2 in tmpdir/common1a.o to 21 in tmpdir/common1b.o" $link_output] } {
    210         fail $test1w1
    211     } else {
    212         pass $test1w1
    213     }
    214 }
    215 
    216 if { [dump_common1 $test1c1] } {
    217     pass $test1c1
    218 }
    219 
    220 set options "-r tmpdir/common1b.o tmpdir/common1a.o"
    221 
    222 # SH64 targets needs an extra ld option for this test.
    223 if [istarget sh64*-*-*] {
    224     if [istarget sh64*l*-*-*] {
    225 	set options "-mshlelf32 $options"
    226     } else {
    227 	set options "-mshelf32 $options"
    228     }
    229 }
    230 
    231 if { [ld_simple_link $ld tmpdir/common1.o $options] } {
    232     unresolved $test1w2
    233     return
    234 }
    235 
    236 if { ![regexp "Warning: alignment (\[0-9\]+) of symbol \`_?foo1\' in tmpdir/common1b.o is smaller than 64 in tmpdir/common1a.o" $link_output] } {
    237     fail $test1w2
    238 } else {
    239     pass $test1w2
    240 }
    241 
    242 if { [dump_common1 $test1c2] } {
    243     pass $test1c2
    244 }
    245 
    246 #
    247 # The following tests are for when we are generating STT_COMMON symbols only.
    248 #
    249 # Handling of -z common and -z nocommon flags is enabled only if
    250 # $GENERATE_SHLIB_SCRIPT is turned on in emulparams i.e. shared
    251 # libraries are supported.
    252 
    253 if ![check_shared_lib_support]  {
    254     return
    255 }
    256 
    257 stt_common_test "-static -e 0" "static link of common symbols"
    258 stt_common_test "-shared"      "shared link of common symbols"
    259 stt_common_test "-pie"         "position independent link of common symbols"
    260 
    261 run_ld_link_tests [list \
    262   [list \
    263     "Build common-3x.o" \
    264      "-r" "" "--elf-stt-common=no" \
    265      {common-1.s} {} "common-3x.o" \
    266   ] \
    267   [list \
    268     "Build common-3y.o" \
    269      "-r" "" "--elf-stt-common=yes" \
    270      {common-1.s} {} "common-3y.o" \
    271   ] \
    272   [list \
    273     "Build common-3a.o" \
    274     "-r tmpdir/common-3x.o tmpdir/common-3y.o" "" "" \
    275     {dummy.s} {{readelf {-s -W} common-3a.rd}} "common-3a.o" \
    276   ] \
    277   [list \
    278     "Build common-3b.o" \
    279     "-r tmpdir/common-3y.o tmpdir/common-3x.o" "" "" \
    280     {dummy.s} {{readelf {-s -W} common-3b.rd}} "common-3b.o" \
    281   ] \
    282   [list \
    283     "Build common-3c.o" \
    284     "-r -z nocommon tmpdir/common-3x.o tmpdir/common-3y.o" "" "" \
    285     {dummy.s} {{readelf {-s -W} common-3a.rd}} "common-3c.o" \
    286   ] \
    287   [list \
    288     "Build common-3d.o" \
    289     "-r -z common tmpdir/common-3x.o tmpdir/common-3y.o" "" "" \
    290     {dummy.s} {{readelf {-s -W} common-3b.rd}} "common-3b.o" \
    291   ] \
    292   [list \
    293     "Build common-3e.o" \
    294     "-r -z common tmpdir/common-3y.o tmpdir/common-3x.o" "" "" \
    295     {dummy.s} {{readelf {-s -W} common-3b.rd}} "common-3e.o" \
    296   ] \
    297   [list \
    298     "Build common-3f.o" \
    299     "-r -z nocommon tmpdir/common-3y.o tmpdir/common-3x.o" "" "" \
    300     {dummy.s} {{readelf {-s -W} common-3a.rd}} "common-3f.o" \
    301   ] \
    302 ]
    303 
    304 set test_list [lsort [glob -nocomplain $srcdir/$subdir/*.d]]
    305 foreach t $test_list {
    306     # We need to strip the ".d", but can leave the dirname.
    307     verbose [file rootname $t]
    308     run_dump_test [file rootname $t]
    309 }
    310