1# Expect script for linker support of STB_GNU_UNIQUE symbols 2# 3# Copyright (C) 2009-2014 Free Software Foundation, Inc. 4# Contributed by Red Hat. 5# 6# This file is part of the GNU Binutils. 7# 8# This program is free software; you can redistribute it and/or modify 9# it under the terms of the GNU General Public License as published by 10# the Free Software Foundation; either version 3 of the License, or 11# (at your option) any later version. 12# 13# This program is distributed in the hope that it will be useful, 14# but WITHOUT ANY WARRANTY; without even the implied warranty of 15# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16# GNU General Public License for more details. 17# 18# You should have received a copy of the GNU General Public License 19# along with this program; if not, write to the Free Software 20# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 21# MA 02110-1301, USA. 22# 23# Written by Nick Clifton <nickc@redhat.com> 24# Adapted for unique checking by Mark J. Wielaard <mjw@redhat.com> 25 26 27# STB_GNU_UNIQUE support has only been implemented for the ix86, x86_64, 28# arm, powerpc, and sparc so far. 29if {!(([istarget "i?86-*-*"] 30 || [istarget "x86_64-*-*"] 31 || [istarget "arm*-*-*"] 32 || [istarget "powerpc*-*-*"] 33 || [istarget "sparc*-*-*"]) 34 && ([istarget "*-*-elf*"] 35 || [istarget "*-*-nacl*"] 36 || (([istarget "*-*-linux*"] 37 || [istarget "*-*-gnu*"]) 38 && ![istarget "*-*-*aout*"] 39 && ![istarget "*-*-*oldld*"]))) } { 40 verbose "UNIQUE tests not run - target does not support UNIQUE" 41 return 42} 43 44# We need a native system. FIXME: Strictly speaking this 45# is not true, we just need to know how to create a fully 46# linked executable, including the C and Z libraries, using 47# the linker that is under test. 48if ![isnative] { 49 verbose "UNIQUE tests not run - not a native toolchain" 50 return 51} 52 53# We need a working compiler. (Strictly speaking this is 54# not true, we could use target specific assembler files). 55if { [which $CC] == 0 } { 56 verbose "UNIQUE tests not run - no compiler available" 57 return 58} 59 60# A procedure to check the OS/ABI field in the ELF header of a binary file. 61proc check_osabi { binary_file expected_osabi } { 62 global READELF 63 global READELFFLAGS 64 65 catch "exec $READELF $READELFFLAGS --file-header $binary_file > readelf.out" got 66 67 if ![string match "" $got] then { 68 verbose "proc check_osabi: Readelf produced unexpected out processing $binary_file: $got" 69 return 0 70 } 71 72 if { ![regexp "\n\[ \]*OS/ABI:\[ \]*(.+)\n\[ \]*ABI" \ 73 [file_contents readelf.out] nil osabi] } { 74 verbose "proc check_osabi: Readelf failed to extract an ELF header from $binary_file" 75 return 0 76 } 77 78 if { $osabi == $expected_osabi } { 79 return 1 80 } 81 82 verbose "Expected OSABI: $expected_osabi, Obtained osabi: $osabi" 83 84 return 0 85} 86 87# A procedure to confirm that a file contains the UNIQUE symbol. 88# Returns -1 upon error, 0 if the symbol was not found and 1 if it was found. 89proc contains_unique_symbol { binary_file } { 90 global READELF 91 global READELFFLAGS 92 93 catch "exec $READELF $READELFFLAGS --symbols $binary_file > readelf.out" got 94 95 if ![string match "" $got] then { 96 verbose "proc contains_unique_symbol: Readelf produced unexpected out processing $binary_file: $got" 97 return -1 98 } 99 100 # Look for a line like this: 101 # 54: 0000000000400474 4 OBJECT UNIQUE DEFAULT 13 a 102 103 if { ![regexp ".*\[ \]*OBJECT\[ \]+UNIQUE\[ \]+DEFAULT\[ \]+\[UND0-9\]+\[ \]+\[ab\]\n" [file_contents readelf.out]] } { 104 return 0 105 } 106 107 return 1 108} 109 110set fails 0 111 112# Create object file containing unique symbol. 113if ![ld_compile "$CC -c" "$srcdir/$subdir/unique.s" "tmpdir/unique.o"] { 114 fail "Could not create a unique object" 115 set fails [expr $fails + 1] 116} 117 118# Create object file NOT containing unique symbol. 119if ![ld_compile "$CC -c" "$srcdir/$subdir/unique_empty.s" "tmpdir/unique_empty.o"] { 120 fail "Could not create a non-unique object" 121 set fails [expr $fails + 1] 122} 123 124# Create pic object file containing unique symbol. 125if ![ld_compile "$CC -c -fPIC" "$srcdir/$subdir/unique_shared.s" "tmpdir/unique_shared.o"] { 126 fail "Could not create a pic unique object" 127 set fails [expr $fails + 1] 128} 129 130# Create executable containing unique symbol. 131if ![default_ld_link $ld "tmpdir/unique_prog" "tmpdir/unique.o"] { 132 fail "Could not link a unique executable" 133 set fails [expr $fails + 1] 134} 135 136# Create shared library containing unique symbol. 137if ![ld_simple_link $ld "tmpdir/libunique_shared.so" "-shared tmpdir/unique_shared.o"] { 138 fail "Could not create a shared library containing an unique symbol" 139 set fails [expr $fails + 1] 140} 141 142# Create executable NOT containing unique symbol linked against library. 143if ![default_ld_link $ld "tmpdir/unique_shared_prog" "-Ltmpdir tmpdir/unique_empty.o -Bdynamic -lunique_shared -rpath ./tmpdir"] { 144 fail "Could not link a dynamic executable" 145 set fails [expr $fails + 1] 146} 147 148# Create shared library containing unique symbol with reference. 149if ![ld_simple_link $ld "tmpdir/libunique_shared_ref.so" "-shared tmpdir/unique_shared.o tmpdir/unique_empty.o"] { 150 fail "Could not create a shared library containing an unique symbol with reference" 151 set fails [expr $fails + 1] 152} 153 154if { $fails != 0 } { 155 return 156} 157 158# Check the object file. 159if {! [check_osabi tmpdir/unique.o {UNIX - GNU}]} { 160 fail "Object containing unique does not have an OS/ABI field of GNU" 161 set fails [expr $fails + 1] 162} 163 164if {[contains_unique_symbol tmpdir/unique.o] != 1} { 165 fail "Object containing unique does not contain an UNIQUE symbol" 166 set fails [expr $fails + 1] 167} 168 169if { $fails == 0 } { 170 pass "Checking unique object" 171} 172 173# Check the executable. 174if {! [check_osabi tmpdir/unique_prog {UNIX - GNU}]} { 175 fail "Executable containing unique does not have an OS/ABI field of GNU" 176 set fails [expr $fails + 1] 177} 178 179if {[contains_unique_symbol tmpdir/unique_prog] != 1} { 180 fail "Executable containing unique does not contain an UNIQUE symbol" 181 set fails [expr $fails + 1] 182} 183 184if { $fails == 0 } { 185 pass "Checking unique executable" 186} 187 188# Check the empty object file. 189if {! [check_osabi tmpdir/unique_empty.o {UNIX - System V}]} { 190 fail "Object NOT containing unique does not have an OS/ABI field of System V" 191 set fails [expr $fails + 1] 192} 193 194if {[contains_unique_symbol tmpdir/unique_empty.o] == 1} { 195 fail "Object NOT containing unique does contain an UNIQUE symbol" 196 set fails [expr $fails + 1] 197} 198 199if { $fails == 0 } { 200 pass "Checking empty unique object" 201} 202 203# Check the unique PIC file. 204if {! [check_osabi tmpdir/unique_shared.o {UNIX - GNU}]} { 205 fail "PIC Object containing unique does not have an OS/ABI field of GNU" 206 set fails [expr $fails + 1] 207} 208 209if {[contains_unique_symbol tmpdir/unique_shared.o] != 1} { 210 fail "PIC Object containing unique does not contain an UNIQUE symbol" 211 set fails [expr $fails + 1] 212} 213 214if { $fails == 0 } { 215 pass "Checking unique PIC object" 216} 217 218# Check the unique shared library. 219if {! [check_osabi tmpdir/libunique_shared.so {UNIX - GNU}]} { 220 fail "Shared library containing unique does not have an OS/ABI field of GNU" 221 set fails [expr $fails + 1] 222} 223 224if {[contains_unique_symbol tmpdir/libunique_shared.so] != 1} { 225 fail "Shared library containing unique does not contain an UNIQUE symbol" 226 set fails [expr $fails + 1] 227} 228 229# Check the unique shared library with reference. 230if {! [check_osabi tmpdir/libunique_shared_ref.so {UNIX - GNU}]} { 231 fail "Shared library containing unique with reference does not have an OS/ABI field of GNU" 232 set fails [expr $fails + 1] 233} 234 235if {[contains_unique_symbol tmpdir/libunique_shared_ref.so] != 1} { 236 fail "Shared library containing unique with reference does not contain an UNIQUE symbol" 237 set fails [expr $fails + 1] 238} 239 240if { $fails == 0 } { 241 pass "Checking unique PIC object" 242} 243 244# Check the empty executable linked against unique shared library. 245if {! [check_osabi tmpdir/unique_shared_prog {UNIX - System V}]} { 246 fail "Executable NOT containing unique does not have an OS/ABI field of System V" 247 set fails [expr $fails + 1] 248} 249 250if {[contains_unique_symbol tmpdir/unique_shared_prog] == 1} { 251 fail "Executable NOT containing unique does contain an UNIQUE symbol" 252 set fails [expr $fails + 1] 253} 254 255if { $fails == 0 } { 256 pass "Checking shared empty executable" 257} 258 259# Clean up, unless we are being verbose, in which case we leave the files available. 260if { $verbose < 1 } { 261 remote_file host delete "tmpdir/unique_empty.o" 262 remote_file host delete "tmpdir/unique.o" 263 remote_file host delete "tmpdir/unique_shared.o" 264 remote_file host delete "tmpdir/libunique_shared.so" 265 remote_file host delete "tmpdir/libunique_shared_ref.so" 266 remote_file host delete "tmpdir/unique_prog" 267 remote_file host delete "tmpdir/unique_shared_prog" 268} 269