1 # Test linking directly to S-records. 2 # By Ian Lance Taylor, Cygnus Support. 3 # Copyright (C) 1999-2016 Free Software Foundation, Inc. 4 # 5 # This file is part of the GNU Binutils. 6 # 7 # This program is free software; you can redistribute it and/or modify 8 # it under the terms of the GNU General Public License as published by 9 # the Free Software Foundation; either version 3 of the License, or 10 # (at your option) any later version. 11 # 12 # This program is distributed in the hope that it will be useful, 13 # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 # GNU General Public License for more details. 16 # 17 # You should have received a copy of the GNU General Public License 18 # along with this program; if not, write to the Free Software 19 # Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 20 # MA 02110-1301, USA. 21 22 # Get the offset from an S-record line to the start of the data. 23 24 proc srec_off { l } { 25 if [string match "S1*" $l] { 26 return 8 27 } else { if [string match "S2*" $l] { 28 return 10 29 } else { if [string match "S3*" $l] { 30 return 12 31 } else { 32 return -1 33 } } } 34 } 35 36 # See if an S-record line contains only zero data. 37 38 proc srec_zero { l } { 39 if [string match "S\[0789\]*" $l] { 40 return 1 41 } 42 43 # Strip the address and checksum. 44 if [string match "S\[123\]*" $l] { 45 set l [string range $l [srec_off $l] [expr [string length $l] - 3]] 46 } else { 47 return 0 48 } 49 50 # The rest must be zero. 51 return [string match "" [string trim $l "0"]] 52 } 53 54 # Get the address of an S-record line. 55 56 proc srec_addr { l } { 57 if [string match "S\[123\]*" $l] { 58 set addr [string range $l 4 [expr [srec_off $l] - 1]] 59 } else { 60 return -1 61 } 62 63 return "0x$addr" 64 } 65 66 # Get the number of data bytes in an S-record line. 67 68 proc srec_len { l } { 69 if ![string match "S\[123\]*" $l] { 70 return 0 71 } 72 73 return [expr "0x[string range $l 2 3]" - ([srec_off $l] - 4) / 2 - 1] 74 } 75 76 # Extract bytes from an S-record line. 77 78 proc srec_extract { l start len } { 79 set off [srec_off $l] 80 set rlen [srec_len $l] 81 set stop [expr $start + $len] 82 if { $stop > $rlen } { 83 set stop [expr $rlen] 84 } 85 set start [expr $start * 2 + $off] 86 set stop [expr $stop * 2 + $off - 1] 87 return [string range $l $start $stop] 88 } 89 90 # See if a range of bytes in an S-record line is all zeroes. 91 92 proc srec_zero_range { l start len } { 93 return [string match "" [string trim [srec_extract $l $start $len] "0"]] 94 } 95 96 # Trim an S-record line such that the specified number of bytes remain 97 # at the end. 98 99 proc srec_trim { l leave } { 100 set off [srec_off $l] 101 set addr [srec_addr $l] 102 set len [srec_len $l] 103 104 if { $leave >= $len } { 105 return $l 106 } 107 108 set s1 [string range $l 0 1] 109 set s2 [format "%02x" [expr ($off - 4) / 2 + $leave + 1]] 110 set s3 [format "%0[expr $off - 4]x" [expr $addr + $len - $leave]] 111 set s4 [string range $l [expr [string length $l] - ($leave * 2) - 2] end] 112 set s "${s1}${s2}${s3}${s4}" 113 114 verbose "srec_trim { '$l' $leave } returning '$s'" 2 115 116 return $s 117 } 118 119 # Report failure when comparing S-record lines 120 121 proc srec_compare_fail { which l1 l2 } { 122 send_log "comparison failure $which:\n$l1\n$l2\n" 123 verbose "comparison failure $which:\n$l1\n$l2" 124 } 125 126 # Compare S-record files. We don't want to fuss about things like 127 # extra zeroes. Note that BFD always sorts S-records by address. 128 129 proc srec_compare { f1 f2 } { 130 set e1 [gets $f1 l1] 131 set e2 [gets $f2 l2] 132 133 while { $e1 != -1 } { 134 set l1 [string trimright $l1 "\r\n"] 135 set l2 [string trimright $l2 "\r\n"] 136 if { $e2 == -1 } { 137 # If l1 contains data, it must be zero. 138 if ![srec_zero $l1] { 139 send_log "data after EOF: $l1\n" 140 verbose "data after EOF: $l1" 141 return 0 142 } 143 } else { if { [string compare $l1 $l2] == 0 } { 144 set e1 [gets $f1 l1] 145 set e2 [gets $f2 l2] 146 } else { if { [srec_zero $l1] } { 147 set e1 [gets $f1 l1] 148 } else { if { [srec_zero $l2] } { 149 set e2 [gets $f2 l2] 150 } else { 151 # The strings are not the same, and neither is all zeroes. 152 set a1 [srec_addr $l1] 153 set n1 [srec_len $l1] 154 set a2 [srec_addr $l2] 155 set n2 [srec_len $l2] 156 157 if { $a1 < $a2 && ![srec_zero_range $l1 0 [expr $a2 - $a1]] } { 158 verbose "$a1 $a2 [srec_extract $l1 0 [expr $a2 - $a1]]" 2 159 srec_compare_fail 1 $l1 $l2 160 return 0 161 } 162 if { $a2 < $a1 && ![srec_zero_range $l2 0 [expr $a1 - $a2]] } { 163 srec_compare_fail 2 $l1 $l2 164 return 0 165 } 166 167 # Here we know that any initial data in both lines is 168 # zero. Now make sure that any overlapping data matches. 169 if { $a1 < $a2 } { 170 set os1 [expr $a2 - $a1] 171 set os2 0 172 } else { 173 set os1 0 174 set os2 [expr $a1 - $a2] 175 } 176 if { $a1 + $n1 < $a2 + $n2 } { 177 set ol [expr $n1 - $os1] 178 } else { 179 set ol [expr $n2 - $os2] 180 } 181 182 set x1 [srec_extract $l1 $os1 $ol] 183 set x2 [srec_extract $l2 $os2 $ol] 184 if { [string compare $x1 $x2] != 0 } { 185 verbose "$os1 $ol $x1" 2 186 verbose "$os2 $ol $x2" 2 187 srec_compare_fail 3 $l1 $l2 188 return 0 189 } 190 191 # These strings match. Trim the data from the larger 192 # string, read a new copy of the smaller string, and 193 # continue. 194 if { $a1 + $n1 < $a2 + $n2 } { 195 set l2 [srec_trim $l2 [expr ($a2 + $n2) - ($a1 + $n1)]] 196 set e1 [gets $f1 l1] 197 } else { if { $a1 + $n1 > $a2 + $n2 } { 198 set l1 [srec_trim $l1 [expr ($a1 + $n1) - ($a2 + $n2)]] 199 set e2 [gets $f2 l2] 200 } else { 201 set e1 [gets $f1 l1] 202 set e2 [gets $f2 l2] 203 } } 204 } } } } 205 } 206 207 # We've reached the end of the first file. The remainder of the 208 # second file must contain only zeroes. 209 while { $e2 != -1 } { 210 set l2 [string trimright $l2 "\r\n"] 211 if ![srec_zero $l2] { 212 send_log "data after EOF: $l2\n" 213 verbose "data after EOF: $l2" 214 return 0 215 } 216 set e2 [gets $f2 l2] 217 } 218 219 return 1 220 } 221 222 # Link twice, objcopy, and compare 223 224 proc run_srec_test { test objs } { 225 global ld 226 global objcopy 227 global sizeof_headers 228 global host_triplet 229 230 # Tell the ELF linker to not do anything clever with .eh_frame, 231 # not to put anything in small data, and define various symbols. 232 set flags "--traditional-format -G 0 " 233 append flags [ld_simple_link_defsyms] 234 235 # If the linker script uses SIZEOF_HEADERS, use a -Ttext argument 236 # to force both the normal link and the S-record link to be put in 237 # the same place. We don't always use -Ttext because it interacts 238 # poorly with a.out. 239 240 if { $sizeof_headers } { 241 set flags "$flags -Ttext 0x1000" 242 } 243 244 # ARM targets cannot convert format in the linker 245 # using the --oformat command line switch 246 if {[istarget aarch64*-*-*] || \ 247 [istarget arm*-*-*]} { 248 setup_xfail "aarch64-*-*" 249 setup_xfail "aarch64_be-*-*" 250 setup_xfail "arm*-*-*" 251 } 252 253 # The AVR target does not correctly process 254 # relocs when output format is not ELF. 255 if [istarget avr-*-*] { 256 setup_xfail "avr-*-*" 257 } 258 259 # Epiphany needs some help too 260 if [istarget epiphany*-*-*] { 261 set flags "$flags --defsym _start=00000060" 262 setup_xfail "epiphany*-*-*" 263 } 264 265 if [istarget m681*-*-*] { 266 set flags "$flags --defsym _start=0xc000" 267 setup_xfail "m681*-*-*" 268 } 269 270 if [istarget m68hc1*-*-*] { 271 set flags "$flags --defsym _start=0xc000" 272 setup_xfail "m68hc1*-*-*" 273 } 274 275 if [istarget m9s12x*-*-*] { 276 set flags "$flags --defsym _start=0xc000" 277 setup_xfail "m9s12x*-*-*" 278 } 279 280 # MSP430 targets always relax. 281 if [istarget msp430*-*-*] { 282 setup_xfail "msp430*-*-*" 283 } 284 285 # SH64 targets cannot convert format in the linker 286 # using the -oformat command line switch. 287 if [istarget sh64*-*-elf] { 288 # This is what gcc passes to ld by default. 289 set flags "$flags -mshelf32" 290 setup_xfail "sh64*-*-*" 291 } 292 293 # V850 targets need libgcc.a 294 if [istarget v850*-*-elf] { 295 set objs "$objs -L ../gcc -lgcc" 296 } 297 298 # Xtensa ELF targets relax by default; S-Record linker does not 299 if [istarget xtensa*-*-*] { 300 set flags "$flags -no-relax" 301 } 302 303 if { ![ld_simple_link $ld tmpdir/sr1 "$flags $objs"] \ 304 || ![ld_simple_link $ld tmpdir/sr2.sr "$flags --oformat srec $objs"] } { 305 fail $test 306 return 307 } 308 309 send_log "$objcopy -O srec tmpdir/sr1 tmpdir/sr1.sr\n" 310 set exec_output [run_host_cmd "$objcopy" "-O srec tmpdir/sr1 tmpdir/sr1.sr"] 311 set exec_output [prune_warnings $exec_output] 312 if ![string match "" $exec_output] { 313 send_log "$exec_output\n" 314 verbose "$exec_output" 315 unresolved $test 316 return 317 } 318 319 set f1 [open tmpdir/sr1.sr r] 320 set f2 [open tmpdir/sr2.sr r] 321 if [srec_compare $f1 $f2] { 322 pass $test 323 } else { 324 fail $test 325 } 326 close $f1 327 close $f2 328 } 329 330 set test1 "S-records" 331 set test2 "S-records with constructors" 332 333 # See whether the default linker script uses SIZEOF_HEADERS. 334 set exec_output [run_host_cmd "$ld" "--verbose"] 335 set sizeof_headers [string match "*SIZEOF_HEADERS*" $exec_output] 336 337 # First test linking a C program. We don't require any libraries. We 338 # link it normally, and objcopy to the S-record format, and then link 339 # directly to the S-record format, and require that the two files 340 # contain the same data. 341 342 if { ![is_remote host] && [which $CC] == 0 } { 343 untested $test1 344 untested $test2 345 return 346 } 347 348 # Pass -fplt to CC and CXX since -fno-plt doesn't work with S-records 349 # tests. 350 global PLT_CFLAGS 351 set old_CC "$CC" 352 set CC "$CC $PLT_CFLAGS" 353 set old_CXX "$CXX" 354 set CXX "$CXX $PLT_CFLAGS" 355 356 if { ![ld_compile $CC $srcdir/$subdir/sr1.c tmpdir/sr1.o] \ 357 || ![ld_compile $CC $srcdir/$subdir/sr2.c tmpdir/sr2.o] } { 358 unresolved $test1 359 unresolved $test2 360 set CC "$old_CC" 361 set CXX "$old_CXX" 362 return 363 } 364 365 # The i386-aout target is confused: the linker does not put the 366 # sections where objdump finds them. I don't know which is wrong. 367 setup_xfail "i*86-*-aout*" 368 369 # These tests fail on the native MIPS ELF targets because the GP value 370 # in the .reginfo section is not updated when the S-record version is 371 # written out. The mips-elf target itself does not use a .reginfo section. 372 setup_xfail "mips*-*-irix5*" "mips*-*-irix6*" "mips*-*-linux*" 373 374 # The S-record linker doesn't do the magic TOC handling that XCOFF 375 # linkers do. 376 setup_xfail "*-*-aix*" "*-*-xcoff*" 377 378 # The S-record linker is not supported for ARC. 379 setup_xfail "arc*-*-*" 380 381 # The S-record linker doesn't build ARM/Thumb stubs. 382 setup_xfail "arm-*-coff" 383 setup_xfail "arm-*-pe*" 384 # setup_xfail "arm-*elf*" 385 setup_xfail "arm*-*-linux*" 386 387 # The S-record linker doesn't include the .{zda} sections. 388 setup_xfail "v850*-*-elf" 389 390 # The S-record linker doesn't handle Alpha Elf relaxation. 391 setup_xfail "alpha*-*-elf*" "alpha*-*-linux-*" "alpha*-*-gnu*" 392 setup_xfail "alpha*-*-netbsd*" 393 394 # The S-record linker hasn't any hope of coping with HPPA relocs. 395 # Or MeP complex relocs. 396 setup_xfail "hppa*-*-*" "mep-*-*" 397 398 # The S-record linker doesn't handle IA64 Elf relaxation. 399 setup_xfail "ia64-*-*" 400 401 # The S-record linker doesn't support the special PE headers - the PE 402 # emulation tries to write pe-specific information to the PE headers 403 # in the output bfd, but it's not a PE bfd (it's an srec bfd) 404 setup_xfail "*-*-cygwin*" "*-*-mingw*" "*-*-pe*" "*-*-winnt*" 405 setup_xfail "score-*-*" 406 407 # The S-record linker doesn't support Blackfin ELF FDPIC ABI. 408 setup_xfail "bfin-*-linux-uclibc" 409 410 # On tile, we appear to be getting some random-seeming zeroing or 24-bit 411 # rightshifts (!) in the output when directly generating S-records from 412 # the linker. Not clear what could be causing this but we don't 413 # anticipate creating s-records (and could always use objcopy to 414 # generate the format if need be). 415 setup_xfail "tile*-*-*" 416 417 run_srec_test $test1 "tmpdir/sr1.o tmpdir/sr2.o" 418 419 # Now try linking a C++ program with global constructors and 420 # destructors. Note that since we are not linking against any 421 # libraries, this program won't actually work or anything. 422 423 if { ![is_remote host] && [which $CXX] == 0 } { 424 untested $test2 425 set CC "$old_CC" 426 set CXX "$old_CXX" 427 return 428 } 429 430 if ![ld_compile "$CXX $CXXFLAGS -fno-exceptions" $srcdir/$subdir/sr3.cc tmpdir/sr3.o] { 431 unresolved $test2 432 set CC "$old_CC" 433 set CXX "$old_CXX" 434 return 435 } 436 437 # See above. 438 setup_xfail "i*86-*-aout*" 439 setup_xfail "mips*-*-irix5*" "mips*-*-irix6*" "mips*-*-linux*" 440 setup_xfail "*-*-aix*" "*-*-xcoff*" 441 setup_xfail "arc*-*-*" 442 setup_xfail "arm*-*-*" 443 setup_xfail "v850*-*-elf" 444 setup_xfail "alpha*-*-elf*" "alpha*-*-linux-*" "alpha*-*-gnu*" 445 setup_xfail "alpha*-*-netbsd*" 446 setup_xfail "hppa*-*-*" "mep-*-*" 447 setup_xfail "ia64-*-*" 448 setup_xfail "*-*-cygwin*" "*-*-mingw*" "*-*-pe*" "*-*-winnt*" 449 setup_xfail "score-*-*" 450 setup_xfail "bfin-*-linux-uclibc" 451 setup_xfail "tile*-*-*" 452 453 run_srec_test $test2 "tmpdir/sr3.o" 454 455 set CC "$old_CC" 456 set CXX "$old_CXX" 457