1# Copyright 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2# 2004 3# Free Software Foundation, Inc. 4 5# This program is free software; you can redistribute it and/or modify 6# it under the terms of the GNU General Public License as published by 7# the Free Software Foundation; either version 2 of the License, or 8# (at your option) any later version. 9# 10# This program is distributed in the hope that it will be useful, 11# but WITHOUT ANY WARRANTY; without even the implied warranty of 12# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13# GNU General Public License for more details. 14# 15# You should have received a copy of the GNU General Public License 16# along with this program; if not, write to the Free Software 17# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. 18 19# Please email any bugs, comments, and/or additions to this file to: 20# bug-dejagnu@prep.ai.mit.edu 21 22# Written by Ian Lance Taylor <ian@cygnus.com> 23 24if ![is_remote host] { 25 if {[which $OBJCOPY] == 0} then { 26 perror "$OBJCOPY does not exist" 27 return 28 } 29} 30 31send_user "Version [binutil_version $OBJCOPY]" 32 33if ![is_remote host] { 34 set tempfile tmpdir/bintest.o 35 set copyfile tmpdir/copy 36} else { 37 set tempfile [remote_download host tmpdir/bintest.o] 38 set copyfile copy 39} 40 41# Test that objcopy does not modify a file when copying it. 42 43proc objcopy_test {testname srcfile} { 44 global OBJCOPY 45 global OBJCOPYFLAGS 46 global srcdir 47 global subdir 48 global tempfile 49 global copyfile 50 51 if {![binutils_assemble $srcdir/$subdir/${srcfile} tmpdir/bintest.o]} then { 52 perror "unresolved $testname" 53 unresolved "objcopy ($testname)" 54 return 55 } 56 57 set got [binutils_run $OBJCOPY "$OBJCOPYFLAGS $tempfile ${copyfile}.o"] 58 59 if ![string match "" $got] then { 60 fail "objcopy ($testname)" 61 } else { 62 send_log "cmp $tempfile ${copyfile}.o\n" 63 verbose "cmp $tempfile ${copyfile}.o" 64 if [is_remote host] { 65 set src1 tmpdir/bintest.o 66 set src2 tmpdir/copy.o 67 remote_upload host $tempfile $src1 68 remote_upload host ${copyfile}.o $src2 69 } else { 70 set src1 ${tempfile} 71 set src2 ${copyfile}.o 72 } 73 set status [remote_exec build cmp "${src1} ${src2}"] 74 set exec_output [lindex $status 1] 75 set exec_output [prune_warnings $exec_output] 76 77 # On some systems the result of objcopy will not be identical. 78 # Usually this is just because gas isn't using bfd to write the 79 # files in the first place, and may order things a little 80 # differently. Those systems should use setup_xfail here. 81 82 setup_xfail "h8300-*-rtems*" "h8300-*-coff" 83 setup_xfail "h8500-*-rtems*" "h8500-*-coff" 84 setup_xfail "hppa*-*-*" 85 setup_xfail "i960-*" 86 setup_xfail "m68*-*-*coff" "m68*-*-hpux*" "m68*-*-lynxos*" 87 setup_xfail "m68*-*-sysv*" "m68*-apple-aux*" 88 setup_xfail "m8*-*" 89 setup_xfail "or32-*-rtems*" "or32-*-coff" 90 setup_xfail "sh-*-coff*" "sh-*-rtems*" 91 setup_xfail "tic4x-*-*" "tic80-*-*" "w65-*" 92 93 clear_xfail "hppa*64*-*-hpux*" "hppa*-*-linux*" "hppa*-*-lites*" 94 clear_xfail "hppa*-*-*n*bsd*" "hppa*-*-rtems*" "*-*-*elf*" 95 clear_xfail "m68*-*-sysv4*" 96 97 if [string match "" $exec_output] then { 98 pass "objcopy ($testname)" 99 } else { 100 send_log "$exec_output\n" 101 verbose "$exec_output" 1 102 103 # On OSF/1, this succeeds with gas and fails with /bin/as. 104 setup_xfail "alpha*-*-osf*" 105 106 # This fails for COFF i960-vxworks targets. 107 setup_xfail "i960-*-vxworks*" 108 109 fail "objcopy ($testname)" 110 } 111 } 112} 113 114objcopy_test "simple copy" bintest.s 115 116# Test generating S records. 117 118# We make the srec filename 8.3 compatible. Note that the header string 119# matched against depends on the name of the file. Ugh. 120 121if [is_remote host] { 122 set srecfile copy.sre 123 set header_string S00B0000636F70792E737265C1 124} else { 125 set srecfile ${copyfile}.srec 126 set header_string S0130000746D706469722F636F70792E7372656397 127} 128 129set got [binutils_run $OBJCOPY "$OBJCOPYFLAGS -O srec $tempfile ${srecfile}"] 130 131if ![string match "" $got] then { 132 fail "objcopy -O srec" 133} else { 134 if [is_remote host] { 135 remote_upload host ${srecfile} tmpdir/copy.srec 136 set srecfile tmpdir/copy.srec 137 } 138 set file [open ${srecfile} r] 139 140 # The first S record is fixed by the file name we are using. 141 gets $file line 142 send_log "$line\n" 143 verbose $line 144 if ![regexp "$header_string.*" $line] { 145 send_log "bad header\n" 146 fail "objcopy -O srec" 147 } else { 148 while {[gets $file line] != -1 \ 149 && [regexp "^S\[123\]\[0-9a-fA-F\]+\[\r\n\]*$" $line]} { 150 send_log "$line\n" 151 verbose $line 152 set line "**EOF**" 153 } 154 send_log "$line\n" 155 verbose $line 156 if ![regexp "^S\[789\]\[0-9a-fA-F\]+\[\r\n\]*$" $line] then { 157 send_log "bad trailer\n" 158 fail "objcopy -O srec" 159 } else { 160 if {[gets $file line] != -1} then { 161 send_log "garbage at end\n" 162 send_log "$line\n" 163 verbose $line 164 fail "objcopy -O srec" 165 } else { 166 set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -f ${copyfile}.srec"] 167 if ![regexp "file format srec" $got] then { 168 send_log "objdump failed\n" 169 fail "objcopy -O srec" 170 } else { 171 pass "objcopy -O srec" 172 } 173 } 174 } 175 } 176 177 close $file 178} 179 180# Test setting and adjusting the start address. We only test this 181# while generating S records, because we may not be able to set the 182# start address for other object file formats, and the S record case 183# is the only useful one anyhow. 184 185set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -f $tempfile"] 186if ![regexp "start address (\[0-9a-fA-FxX\]+)" $got all origstart] then { 187 perror "objdump can not recognize bintest.o" 188 set origstart "" 189} else { 190 set got [binutils_run $OBJCOPY "$OBJCOPYFLAGS -O srec --set-start 0x7654 $tempfile ${copyfile}.srec"] 191 if ![string match "" $got] then { 192 fail "objcopy --set-start" 193 } else { 194 set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -f ${copyfile}.srec"] 195 if ![regexp "file format srec.*start address (\[0-9a-fA-FxX\]+)" $got all srecstart] then { 196 fail "objcopy --set-start" 197 } else { 198 if {$srecstart != 0x7654} then { 199 send_log "$srecstart != 0x7654\n" 200 fail "objcopy --set-start" 201 } else { 202 pass "objcopy --set-start" 203 } 204 } 205 } 206 207 set got [binutils_run $OBJCOPY "$OBJCOPYFLAGS -O srec --adjust-start 0x123 $tempfile ${copyfile}.srec"] 208 if ![string match "" $got] then { 209 fail "objcopy --adjust-start" 210 } else { 211 set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -f ${copyfile}.srec"] 212 if ![regexp "file format srec.*start address (\[0-9a-fA-FxX\]+)" $got all srecstart] then { 213 fail "objcopy --adjust-start" 214 } else { 215 if {$srecstart != $origstart + 0x123} then { 216 send_log "$srecstart != $origstart + 0x123\n" 217 fail "objcopy --adjust-start" 218 } else { 219 pass "objcopy --adjust-start" 220 } 221 } 222 } 223} 224 225# Test adjusting the overall VMA, and adjusting the VMA of a 226# particular section. We again only test this when generating S 227# records. 228 229set low "" 230set lowname "" 231 232set headers [binutils_run $OBJDUMP "$OBJDUMPFLAGS -h $tempfile"] 233 234set headers_regexp "\[ 0-9\]+(\[^ \]+)\[ \]*(\[0-9a-fA-F\]+)\[ \]+\[0-9a-fA-F\]+\[ \]+(\[0-9a-fA-F\]+)\[ \]+\[0-9a-fA-F\]+\[ \]+2\[*\]\[*\]\[0-9\]+(.*)" 235 236set got $headers 237while {[regexp $headers_regexp $got all name size vma rest]} { 238 set vma 0x$vma 239 set size 0x$size 240 if {$size != 0} { 241 if {$low == "" || $vma < $low} { 242 set low $vma 243 set lowname $name 244 } 245 } 246 set got $rest 247} 248 249if {$low == "" || $origstart == ""} then { 250 perror "objdump can not recognize bintest.o" 251} else { 252 set got [binutils_run $OBJCOPY "$OBJCOPYFLAGS -O srec --adjust-vma 0x123 $tempfile ${copyfile}.srec"] 253 if ![string match "" $got] then { 254 fail "objcopy --adjust-vma" 255 } else { 256 set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -fh ${copyfile}.srec"] 257 set want "file format srec.*start address\[ \]*(\[0-9a-fA-FxX\]+).*sec1\[ \]+\[0-9a-fA-F\]+\[ \]+(\[0-9a-fA-F\]+)" 258 if ![regexp $want $got all start vma] then { 259 fail "objcopy --adjust-vma" 260 } else { 261 set vma 0x$vma 262 if {$vma != $low + 0x123} then { 263 send_log "$vma != $low + 0x123\n" 264 fail "objcopy --adjust-vma" 265 } else { 266 if {$start != $origstart + 0x123} then { 267 send_log "$start != $origstart + 0x123\n" 268 fail "objcopy --adjust-vma" 269 } else { 270 pass "objcopy --adjust-vma" 271 } 272 } 273 } 274 } 275 276 set arg "" 277 set got $headers 278 while {[regexp $headers_regexp $got all name size vma rest]} { 279 set vma 0x$vma 280 if {$vma == $low} then { 281 set arg "$arg --adjust-section-vma $name+4" 282 } 283 set got $rest 284 } 285 286 set got [binutils_run $OBJCOPY "$OBJCOPYFLAGS -O srec $arg $tempfile ${copyfile}.srec"] 287 if ![string match "" $got] then { 288 fail "objcopy --adjust-section-vma +" 289 } else { 290 set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -h ${copyfile}.srec"] 291 set want "file format srec.*sec1\[ \]+\[0-9a-fA-F\]+\[ \]+(\[0-9a-fA-F\]+)" 292 if ![regexp $want $got all vma] then { 293 fail "objcopy --adjust-section-vma +" 294 } else { 295 set vma 0x$vma 296 if {$vma != $low + 4} then { 297 send_log "$vma != $low + 4\n" 298 fail "objcopy --adjust-section-vma +" 299 } else { 300 pass "objcopy --adjust-section-vma +" 301 } 302 } 303 } 304 305 regsub -all "\\+4" $arg "=[expr $low + 4]" argeq 306 set got [binutils_run $OBJCOPY "$OBJCOPYFLAGS -O srec $argeq $tempfile ${copyfile}.srec"] 307 if ![string match "" $got] then { 308 fail "objcopy --adjust-section-vma =" 309 } else { 310 set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -h ${copyfile}.srec"] 311 set want "file format srec.*sec1\[ \]+\[0-9a-fA-F\]+\[ \]+(\[0-9a-fA-F\]+)" 312 if ![regexp $want $got all vma] then { 313 fail "objcopy --adjust-section-vma =" 314 } else { 315 set vma 0x$vma 316 if {$vma != $low + 4} then { 317 send_log "$vma != $low + 4\n" 318 fail "objcopy --adjust-section-vma =" 319 } else { 320 pass "objcopy --adjust-section-vma =" 321 } 322 } 323 } 324} 325 326# Test stripping an object. 327 328proc strip_test { } { 329 global AR 330 global CC 331 global STRIP 332 global STRIPFLAGS 333 global NM 334 global NMFLAGS 335 global srcdir 336 global subdir 337 338 set test "strip" 339 340 if { [target_compile $srcdir/$subdir/testprog.c tmpdir/testprog.o object debug] != "" } { 341 untested $test 342 return 343 } 344 345 if [is_remote host] { 346 set archive libstrip.a 347 set objfile [remote_download host tmpdir/testprog.o] 348 remote_file host delete $archive 349 } else { 350 set archive tmpdir/libstrip.a 351 set objfile tmpdir/testprog.o 352 } 353 354 remote_file build delete tmpdir/libstrip.a 355 356 set exec_output [binutils_run $AR "rc $archive ${objfile}"] 357 if ![string match "" $exec_output] { 358 fail $test 359 return 360 } 361 362 set exec_output [binutils_run $STRIP "$STRIPFLAGS $archive"] 363 if ![string match "" $exec_output] { 364 fail $test 365 return 366 } 367 368 if { [target_compile $srcdir/$subdir/testprog.c tmpdir/testprog.o object debug] != "" } { 369 untested $test 370 return 371 } 372 373 if [is_remote host] { 374 set objfile [remote_download host tmpdir/testprog.o] 375 } else { 376 set objfile tmpdir/testprog.o 377 } 378 379 set exec_output [binutils_run $STRIP "$STRIPFLAGS $objfile"] 380 if ![string match "" $exec_output] { 381 fail $test 382 return 383 } 384 385 set exec_output [binutils_run $NM "-a $NMFLAGS $objfile"] 386 if ![string match "*: no symbols*" $exec_output] { 387 fail $test 388 return 389 } 390 391 pass $test 392} 393 394strip_test 395 396# Test stripping an object file with saving a symbol 397 398proc strip_test_with_saving_a_symbol { } { 399 global CC 400 global STRIP 401 global STRIPFLAGS 402 global NM 403 global NMFLAGS 404 global srcdir 405 global subdir 406 407 set test "strip with saving a symbol" 408 409 if { [target_compile $srcdir/$subdir/testprog.c tmpdir/testprog.o object debug] != "" } { 410 untested $test 411 return 412 } 413 414 if [is_remote host] { 415 set objfile [remote_download host tmpdir/testprog.o] 416 } else { 417 set objfile tmpdir/testprog.o 418 } 419 420 set exec_output [binutils_run $STRIP "$STRIPFLAGS -K main -K _main $objfile"] 421 if ![string match "" $exec_output] { 422 fail $test 423 return 424 } 425 426 set exec_output [binutils_run $NM "$NMFLAGS $objfile"] 427 if {![regexp {^([0-9a-fA-F]+)?[ ]+[TD] main} $exec_output] \ 428 && ![regexp {^([0-9a-fA-F]+)?[ ]+T _main} $exec_output]} { 429 fail $test 430 return 431 } 432 433 pass $test 434} 435 436strip_test_with_saving_a_symbol 437 438# Build a final executable. 439 440if { [istarget *-*-cygwin] || [istarget *-*-mingw32] } { 441 set test_prog "testprog.exe" 442} else { 443 set test_prog "testprog" 444} 445 446proc copy_setup { } { 447 global srcdir 448 global subdir 449 global gcc_gas_flag 450 global test_prog 451 452 set res [build_wrapper testglue.o] 453 set flags { debug } 454 455 if { $res != "" } { 456 lappend flags "additional_flags=[lindex $res 1]" 457 set add_libs "testglue.o" 458 } else { 459 set add_libs "" 460 } 461 462 if { [istarget *-*-linux*] } { 463 foreach i $gcc_gas_flag { 464 set flags "additional_flags=$i $flags" 465 } 466 } 467 if { [target_compile "$srcdir/$subdir/testprog.c $add_libs" tmpdir/$test_prog executable $flags] != "" } { 468 return 2 469 } 470 471 set result [remote_load target tmpdir/$test_prog] 472 set status [lindex $result 0] 473 474 if { $status != "pass" } { 475 perror "unresolved setup, status = $status" 476 return 3 477 } 478 479 return 0 480} 481 482# Test copying an executable. 483 484proc copy_executable { prog flags test1 test2 } { 485 global test_prog 486 487 if [is_remote host] { 488 set testfile [remote_download host tmpdir/$test_prog] 489 set testcopy copyprog 490 } else { 491 set testfile tmpdir/$test_prog 492 set testcopy tmpdir/copyprog 493 } 494 remote_file host delete $testcopy 495 496 set exec_output [binutils_run $prog "$flags $testfile $testcopy"] 497 498 if ![string match "" $exec_output] { 499 fail $test1 500 fail $test2 501 return 502 } 503 504 if [is_remote host] { 505 remote_upload host $testcopy tmpdir/copyprog 506 } 507 508 set status [remote_exec build "cmp" "tmpdir/$test_prog tmpdir/copyprog"] 509 set exec_output [lindex $status 1] 510 511 if [string match "" $exec_output] then { 512 pass $test1 513 } else { 514 send_log "$exec_output\n" 515 verbose "$exec_output" 516 517 # This will fail for many reasons. For example, it will most 518 # likely fail if a non-GNU linker is used. Therefore, we do 519 # not insist that it pass. If you are using an assembler and 520 # linker based on the same BFD as objcopy, it is worth 521 # investigating to see why this failure occurs. If we are 522 # cross compiling, we assume that a GNU linker is being used, 523 # and expect it to succeed. 524 if {[isnative]} then { 525 setup_xfail "*-*-*" 526 } 527 528 # This also fails for mips*-*-elf targets. See elf32-mips.c 529 # mips_elf_sym_is_global. 530 setup_xfail "mips*-*-elf" 531 532 setup_xfail "*arm*-*-coff" 533 setup_xfail "xscale-*-coff" 534 setup_xfail "arm*-*-pe" 535 setup_xfail "thumb*-*-coff" 536 setup_xfail "thumb*-*-pe" 537 538 fail $test1 539 } 540 541 set output [remote_load target tmpdir/copyprog] 542 set status [lindex $output 0] 543 if { $status != "pass" } { 544 fail $test2 545 } else { 546 pass $test2 547 } 548} 549 550# Test stripping an executable 551 552proc strip_executable { prog flags test } { 553 global NM 554 global NMFLAGS 555 556 remote_download build tmpdir/copyprog tmpdir/striprog 557 if [is_remote host] { 558 set copyfile [remote_download host tmpdir/striprog] 559 } else { 560 set copyfile tmpdir/striprog 561 } 562 563 set exec_output [binutils_run $prog "$flags ${copyfile}"] 564 if ![string match "" $exec_output] { 565 fail $test 566 return 567 } 568 569 if [is_remote host] { 570 remote_upload host ${copyfile} tmpdir/striprog 571 } 572 573 set result [remote_load target tmpdir/striprog] 574 set status [lindex $result 0] 575 if { $status != "pass" } { 576 fail $test 577 return 578 } 579 580 set exec_output [binutils_run $NM "$NMFLAGS ${copyfile}"] 581 if ![string match "*: no symbols*" $exec_output] { 582 fail $test 583 return 584 } 585 pass $test 586} 587 588# Test stripping an executable with saving a symbol 589 590proc strip_executable_with_saving_a_symbol { prog flags test } { 591 global NM 592 global NMFLAGS 593 594 remote_download build tmpdir/copyprog tmpdir/striprog 595 if [is_remote host] { 596 set copyfile [remote_download host tmpdir/striprog] 597 } else { 598 set copyfile tmpdir/striprog 599 } 600 601 set exec_output [binutils_run $prog "$flags ${copyfile}"] 602 if ![string match "" $exec_output] { 603 fail $test 604 return 605 } 606 607 if [is_remote host] { 608 remote_upload host ${copyfile} tmpdir/striprog 609 } 610 611 set result [remote_load target tmpdir/striprog] 612 set status [lindex $result 0] 613 if { $status != "pass" } { 614 fail $test 615 return 616 } 617 618 set exec_output [binutils_run $NM "$NMFLAGS ${copyfile}"] 619 if { [istarget mmix-knuth-mmixware] } { 620 # Whenever there's a symbol in the mmo format, there's the symbol 621 # Main, so remove it manually from the expected output for sake of 622 # this test. 623 624 # Using "" not {} to get the \n and \r translated. 625 regsub "^\[0-9a-fA-F\]+\[ \]+T Main\[\n\r\]+" $exec_output "" exec_output 626 } 627 628 if {![regexp {^([0-9a-fA-F]+)?[ ]+[TD] main} $exec_output] \ 629 && ![regexp {^([0-9a-fA-F]+)?[ ]+[TD] _main} $exec_output]} { 630 fail $test 631 return 632 } 633 pass $test 634} 635 636set test1 "simple objcopy of executable" 637set test2 "run objcopy of executable" 638set test3 "run stripped executable" 639set test4 "run stripped executable with saving a symbol" 640 641switch [copy_setup] { 642 "1" { 643 # do nothing 644 } 645 "2" { 646 untested $test1 647 untested $test2 648 untested $test3 649 untested $test4 650 } 651 "3" { 652 unresolved $test1 653 unresolved $test2 654 unresolved $test3 655 unresolved $test4 656 } 657 "0" { 658 copy_executable "$OBJCOPY" "$OBJCOPYFLAGS" "$test1" "$test2" 659 strip_executable "$STRIP" "$STRIPFLAGS" "$test3" 660 strip_executable_with_saving_a_symbol "$STRIP" "-K main -K _main $STRIPFLAGS" "$test4" 661 } 662} 663 664proc objcopy_test_readelf {testname srcfile} { 665 global OBJCOPY 666 global OBJCOPYFLAGS 667 global READELF 668 global srcdir 669 global subdir 670 671 if {![binutils_assemble $srcdir/$subdir/${srcfile} tmpdir/bintest.o]} then { 672 unresolved "objcopy ($testname)" 673 return 674 } 675 676 verbose -log "$OBJCOPY $OBJCOPYFLAGS tmpdir/bintest.o tmpdir/copy.o" 677 catch "exec $OBJCOPY $OBJCOPYFLAGS tmpdir/bintest.o tmpdir/copy.o" exec_output 678 if ![string match "" $exec_output] then { 679 fail "objcopy ($testname)" 680 return; 681 } 682 683 verbose -log "$READELF -a tmpdir/bintest.o > tmpdir/bintest.o.out" 684 catch "exec $READELF -a tmpdir/bintest.o > tmpdir/bintest.o.out" exec_output 685 set exec_output [prune_warnings $exec_output] 686 if ![string match "" $exec_output] then { 687 unresolved "objcopy ($testname)" 688 return 689 } 690 691 verbose -log "$READELF -a tmpdir/copy.o > tmpdir/copy.o.out" 692 catch "exec $READELF -a tmpdir/copy.o > tmpdir/copy.o.out" exec_output 693 set exec_output [prune_warnings $exec_output] 694 if ![string match "" $exec_output] then { 695 unresolved "objcopy ($testname)" 696 return 697 } 698 699 verbose -log "diff tmpdir/bintest.o.out tmpdir/copy.o.out" 700 catch "exec diff tmpdir/bintest.o.out tmpdir/copy.o.out" exec_output 701 set exec_output [prune_warnings $exec_output] 702 703 if [string match "" $exec_output] then { 704 pass "objcopy ($testname)" 705 } else { 706 fail "objcopy ($testname)" 707 } 708} 709 710# ia64 specific tests 711if { ([istarget "ia64-*-elf*"] 712 || [istarget "ia64-*-linux*"]) } { 713 objcopy_test "ia64 link order" link-order.s 714} 715 716# ELF specific tests 717if [is_elf_format] { 718 objcopy_test "ELF unknown section type" unknown.s 719 objcopy_test_readelf "ELF group" group.s 720} 721