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