1#   Copyright (C) 1994-2016 Free Software Foundation, Inc.
2
3# This program is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License as published by
5# the Free Software Foundation; either version 3 of the License, or
6# (at your option) any later version.
7#
8# This program is distributed in the hope that it will be useful,
9# but WITHOUT ANY WARRANTY; without even the implied warranty of
10# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11# GNU General Public License for more details.
12#
13# You should have received a copy of the GNU General Public License
14# along with this program; if not, write to the Free Software
15# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
16
17# Please email any bugs, comments, and/or additions to this file to:
18# bug-dejagnu@prep.ai.mit.edu
19
20# Written by Ian Lance Taylor <ian@cygnus.com>
21
22if ![is_remote host] {
23    if {[which $OBJCOPY] == 0} then {
24        perror "$OBJCOPY does not exist"
25        return
26    }
27}
28
29send_user "Version [binutil_version $OBJCOPY]"
30
31if ![is_remote host] {
32    set tempfile tmpdir/bintest.o
33    set copyfile tmpdir/copy
34} else {
35    set tempfile [remote_download host tmpdir/bintest.o]
36    set copyfile copy
37}
38
39# Test that objcopy does not modify a file when copying it.
40
41proc objcopy_test {testname srcfile} {
42    global OBJCOPY
43    global OBJCOPYFLAGS
44    global srcdir
45    global subdir
46    global tempfile
47    global copyfile
48
49    if {![binutils_assemble $srcdir/$subdir/${srcfile} $tempfile]} then {
50 	perror "unresolved $testname"
51	unresolved "objcopy ($testname)"
52	remote_file host delete $tempfile
53	return
54    }
55
56    set got [binutils_run $OBJCOPY "$OBJCOPYFLAGS $tempfile ${copyfile}.o"]
57
58    if ![string equal "" $got] then {
59	fail "objcopy ($testname)"
60    } else {
61	send_log "cmp $tempfile ${copyfile}.o\n"
62	verbose "cmp $tempfile ${copyfile}.o"
63	if [is_remote host] {
64	    set src1 tmpdir/bintest.o
65	    set src2 tmpdir/copy.o
66	    remote_upload host $tempfile $src1
67	    remote_upload host ${copyfile}.o $src2
68	} else {
69	    set src1 ${tempfile}
70	    set src2 ${copyfile}.o
71	}
72	set status [remote_exec build cmp "${src1} ${src2}"]
73	set exec_output [lindex $status 1]
74	set exec_output [prune_warnings $exec_output]
75
76	# On some systems the result of objcopy will not be identical.
77	# Usually this is just because gas isn't using bfd to write the
78	# files in the first place, and may order things a little
79	# differently. Those systems should use setup_xfail here.
80
81	setup_xfail "h8300-*-coff"
82	setup_xfail "h8500-*-rtems*" "h8500-*-coff"
83	setup_xfail "hppa*-*-*"
84	setup_xfail "i960-*"
85	setup_xfail "m68*-*-*coff" "m68*-*-hpux*" "m68*-*-lynxos*"
86	setup_xfail "m68*-*-sysv*" "m68*-apple-aux*"
87	setup_xfail "m8*-*"
88	setup_xfail "sh-*-coff*"
89	setup_xfail "tic80-*-*" "w65-*"
90
91	clear_xfail "hppa*64*-*-hpux*" "hppa*-*-linux*" "hppa*-*-lites*"
92	clear_xfail "hppa*-*-*n*bsd*" "hppa*-*-rtems*" "*-*-*elf*"
93	clear_xfail "m68*-*-sysv4*"
94
95	if [string equal "" $exec_output] then {
96	    pass "objcopy ($testname)"
97	} else {
98	    send_log "$exec_output\n"
99	    verbose "$exec_output" 1
100
101	    # On OSF/1, this succeeds with gas and fails with /bin/as.
102	    setup_xfail "alpha*-*-osf*"
103
104	    fail "objcopy ($testname)"
105	}
106    }
107}
108
109objcopy_test "simple copy" bintest.s
110
111if { [file exists $tempfile] } {
112    # Test reversing bytes in a section.
113
114    set reversed ${tempfile}-reversed
115    set sect_names [get_standard_section_names]
116    if { $sect_names != "" } {
117	set got [binutils_run $OBJCOPY "$OBJCOPYFLAGS -j [lindex $sect_names 1] --reverse-bytes=4 $tempfile $reversed"]
118    } else {
119	set got [binutils_run $OBJCOPY "$OBJCOPYFLAGS -j .data --reverse-bytes=4 $tempfile $reversed"]
120    }
121
122    if ![string equal "" $got] then {
123	fail "objcopy --reverse-bytes"
124    } else {
125	if [is_remote host] {
126	    remote_upload host ${reversed} tmpdir/copy-reversed.o
127	    set reversed tmpdir/copy-reversed.o
128	}
129
130	set origdata [binutils_run $OBJDUMP "$OBJDUMPFLAGS -s -j .data $tempfile"]
131	set  revdata [binutils_run $OBJDUMP "$OBJDUMPFLAGS -s -j .data $reversed"]
132
133	set want "^ \[0-9\]+ (\[0-9\]+)"
134	set found_orig [regexp -lineanchor $want $origdata -> origdata]
135	set found_rev [regexp -lineanchor $want $revdata -> revdata]
136
137	if {$found_orig == 0 || $found_rev == 0} then {
138	    # som doesn't have a .data section
139	    setup_xfail "hppa*-*-hpux*"
140	    clear_xfail "hppa*64*-*-hpux*"
141
142	    fail "objcopy --reverse-bytes"
143	} else {
144	    scan $origdata "%2x%2x%2x%2x" b1 b2 b3 b4
145	    scan $revdata "%2x%2x%2x%2x" c4 c3 c2 c1
146
147	    if {$b1 == $c1 && $b2 == $c2 && $b3 == $c3 && $b4 == $c4} then {
148		pass "objcopy --reverse-bytes"
149	    } else {
150		fail "objcopy --reverse-bytes"
151	    }
152	}
153    }
154}
155
156# Test interleaved copy of multiple byte width
157
158set sequence_file sequence_file
159set file [open ${sequence_file} w]
160puts ${file} "12345678"
161close ${file}
162
163if [is_remote host] {
164    remote_upload host ${sequence_file} tmpdir/sequence_file
165    set sequence_file tmpdir/sequence_file
166}
167
168set got [binutils_run $OBJCOPY "-I binary -i 4 -b 0 --interleave-width 2 ${sequence_file} ${copyfile}"]
169
170if ![string equal "" $got] then {
171    fail "objcopy -i --interleave-width"
172} else {
173    if [is_remote host] {
174	remote_upload host ${copyfile} tmpdir/interleave_output
175	set interleave_output tmpdir/interleave_output
176    } else {
177	set interleave_output ${copyfile}
178    }
179
180    set file [open ${interleave_output} r]
181    gets $file line
182    send_log "$line\n"
183    verbose $line
184
185    if ![string equal "1256" $line] then {
186	fail "objcopy -i --interleave-width"
187    }
188    pass "objcopy -i --interleave-width"
189
190    close $file
191}
192
193# Test generating S records.
194
195if { [file exists $tempfile] } {
196    # We make the srec filename 8.3 compatible. Note that the header string
197    # matched against depends on the name of the file. Ugh.
198
199    if [is_remote host] {
200	set srecfile copy.sre
201	set header_string S00B0000636F70792E737265C1
202    } else {
203	set srecfile ${copyfile}.srec
204	set header_string S0130000746D706469722F636F70792E7372656397
205    }
206
207    set got [binutils_run $OBJCOPY "$OBJCOPYFLAGS -O srec $tempfile ${srecfile}"]
208
209    if ![string equal "" $got] then {
210	fail "objcopy -O srec"
211    } else {
212	if [is_remote host] {
213	    remote_upload host ${srecfile} tmpdir/copy.srec
214	    set srecfile tmpdir/copy.srec
215	}
216	set file [open ${srecfile} r]
217
218	# The first S record is fixed by the file name we are using.
219	gets $file line
220	send_log "$line\n"
221	verbose $line
222	if ![regexp "$header_string.*" $line] {
223	    send_log "bad header\n"
224	    fail "objcopy -O srec"
225	} else {
226	    while {[gets $file line] != -1 \
227		       && [regexp "^S\[123\]\[0-9a-fA-F\]+\[\r\n\]*$" $line]} {
228		send_log "$line\n"
229		verbose $line
230		set line "**EOF**"
231	    }
232	    send_log "$line\n"
233	    verbose $line
234	    if ![regexp "^S\[789\]\[0-9a-fA-F\]+\[\r\n\]*$" $line] then {
235		send_log "bad trailer\n"
236		fail "objcopy -O srec"
237	    } else {
238		if {[gets $file line] != -1} then {
239		    send_log "garbage at end\n"
240		    send_log "$line\n"
241		    verbose $line
242		    fail "objcopy -O srec"
243		} else {
244		    set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -f ${srecfile}"]
245		    if ![regexp "file format srec" $got] then {
246			send_log "objdump failed\n"
247			fail "objcopy -O srec"
248		    } else {
249			pass "objcopy -O srec"
250		    }
251		}
252	    }
253	}
254
255	close $file
256    }
257}
258
259# Test setting and adjusting the start address.  We only test this
260# while generating S records, because we may not be able to set the
261# start address for other object file formats, and the S record case
262# is the only useful one anyhow.
263
264set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -f $tempfile"]
265if ![regexp "start address (\[0-9a-fA-FxX\]+)" $got all origstart] then {
266    perror "objdump can not recognize bintest.o"
267    set origstart ""
268} else {
269    set got [binutils_run $OBJCOPY "$OBJCOPYFLAGS -O srec --set-start 0x7654 $tempfile ${copyfile}.srec"]
270    if ![string equal "" $got] then {
271	fail "objcopy --set-start"
272    } else {
273	set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -f ${copyfile}.srec"]
274	if ![regexp "file format srec.*start address (\[0-9a-fA-FxX\]+)" $got all srecstart] then {
275	    fail "objcopy --set-start"
276	} else {
277	    if {$srecstart != 0x7654} then {
278		send_log "$srecstart != 0x7654\n"
279		fail "objcopy --set-start"
280	    } else {
281		pass "objcopy --set-start"
282	    }
283	}
284    }
285
286    set got [binutils_run $OBJCOPY "$OBJCOPYFLAGS -O srec --adjust-start 0x123 $tempfile ${copyfile}.srec"]
287    if ![string equal "" $got] then {
288	fail "objcopy --adjust-start"
289    } else {
290	set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -f ${copyfile}.srec"]
291	if ![regexp "file format srec.*start address (\[0-9a-fA-FxX\]+)" $got all srecstart] then {
292	    fail "objcopy --adjust-start"
293	} else {
294	    if {$srecstart != $origstart + 0x123} then {
295		send_log "$srecstart != $origstart + 0x123\n"
296		fail "objcopy --adjust-start"
297	    } else {
298		pass "objcopy --adjust-start"
299	    }
300	}
301    }
302}
303
304# Test adjusting the overall VMA, and adjusting the VMA of a
305# particular section.  We again only test this when generating S
306# records.
307
308set low ""
309set lowname ""
310
311set headers [binutils_run $OBJDUMP "$OBJDUMPFLAGS -h $tempfile"]
312
313set headers_regexp "\[ 	0-9\]+(\[^ 	\]+)\[ 	\]*(\[0-9a-fA-F\]+)\[ 	\]+\[0-9a-fA-F\]+\[ 	\]+(\[0-9a-fA-F\]+)\[ 	\]+\[0-9a-fA-F\]+\[ 	\]+2\[*\]\[*\]\[0-9\]+(.*)"
314
315set got $headers
316while {[regexp $headers_regexp $got all name size vma rest]} {
317    set vma 0x$vma
318    set size 0x$size
319    if {$size != 0} {
320	if {$low == "" || $vma < $low} {
321            set low $vma
322	    set lowname $name
323	}
324    }
325    set got $rest
326}
327
328if {$low == "" || $origstart == ""} then {
329    perror "objdump can not recognize bintest.o"
330} else {
331    set got [binutils_run $OBJCOPY "$OBJCOPYFLAGS -O srec --adjust-vma 0x123 $tempfile ${copyfile}.srec"]
332    if ![string equal "" $got] then {
333        fail "objcopy --adjust-vma"
334    } else {
335	set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -fh ${copyfile}.srec"]
336	set want "file format srec.*start address\[ 	\]*(\[0-9a-fA-FxX\]+).*sec1\[ 	\]+\[0-9a-fA-F\]+\[ 	\]+(\[0-9a-fA-F\]+)"
337	if ![regexp $want $got all start vma] then {
338	    fail "objcopy --adjust-vma"
339	} else {
340	    set vma 0x$vma
341	    if {$vma != $low + 0x123} then {
342		send_log "$vma != $low + 0x123\n"
343		fail "objcopy --adjust-vma"
344	    } else {
345		if {$start != $origstart + 0x123} then {
346		    send_log "$start != $origstart + 0x123\n"
347		    fail "objcopy --adjust-vma"
348		} else {
349		    pass "objcopy --adjust-vma"
350		}
351	    }
352	}
353    }
354
355    set arg ""
356    set got $headers
357    while {[regexp $headers_regexp $got all name size vma rest]} {
358	set vma 0x$vma
359	if {$vma == $low} then {
360	    set arg "$arg --adjust-section-vma $name+4"
361	}
362	set got $rest
363    }
364
365    set got [binutils_run $OBJCOPY "$OBJCOPYFLAGS -O srec $arg $tempfile ${copyfile}.srec"]
366    if ![string equal "" $got] then {
367	fail "objcopy --adjust-section-vma +"
368    } else {
369	set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -h ${copyfile}.srec"]
370	set want "file format srec.*sec1\[ 	\]+\[0-9a-fA-F\]+\[ 	\]+(\[0-9a-fA-F\]+)"
371	if ![regexp $want $got all vma] then {
372	    fail "objcopy --adjust-section-vma +"
373	} else {
374	    set vma 0x$vma
375	    if {$vma != $low + 4} then {
376		send_log "$vma != $low + 4\n"
377		fail "objcopy --adjust-section-vma +"
378	    } else {
379		pass "objcopy --adjust-section-vma +"
380	    }
381	}
382    }
383
384    regsub -all "\\+4" $arg "=[expr $low + 4]" argeq
385    set got [binutils_run $OBJCOPY "$OBJCOPYFLAGS -O srec $argeq $tempfile ${copyfile}.srec"]
386    if ![string equal "" $got] then {
387	fail "objcopy --adjust-section-vma ="
388    } else {
389	set got [binutils_run $OBJDUMP "$OBJDUMPFLAGS -h ${copyfile}.srec"]
390	set want "file format srec.*sec1\[ 	\]+\[0-9a-fA-F\]+\[ 	\]+(\[0-9a-fA-F\]+)"
391	if ![regexp $want $got all vma] then {
392	    fail "objcopy --adjust-section-vma ="
393	} else {
394	    set vma 0x$vma
395	    if {$vma != $low + 4} then {
396		send_log "$vma != $low + 4\n"
397		fail "objcopy --adjust-section-vma ="
398	    } else {
399		pass "objcopy --adjust-section-vma ="
400	    }
401	}
402    }
403}
404
405# Test stripping an object.
406
407proc strip_test { } {
408    global AR
409    global CC
410    global STRIP
411    global STRIPFLAGS
412    global NM
413    global NMFLAGS
414    global srcdir
415    global subdir
416    global READELF
417
418    set test "strip"
419
420    if { [target_compile $srcdir/$subdir/testprog.c tmpdir/testprog.o object debug] != "" } {
421	untested $test
422	return
423    }
424
425    set osabi_fail "false"
426    if [is_elf_format] {
427	verbose -log "$READELF -a tmpdir/testprog.o > tmpdir/osabi.in"
428	set exec_output [remote_exec host "$READELF -h tmpdir/testprog.o" "" "/dev/null" "tmpdir/osabi.in"]
429	if { [lindex $exec_output 0] != 0 } then {
430	    unresolved "$test preserving OS/ABI"
431	    set osabi_fail "true"
432	} else {
433	    verbose -log "grep OS/ABI tmpdir/osabi.in"
434	    catch "exec grep OS/ABI tmpdir/osabi.in" osabi_in
435	}
436    }
437
438    if [is_remote host] {
439	set archive libstrip.a
440	set objfile [remote_download host tmpdir/testprog.o]
441	remote_file host delete $archive
442    } else {
443	set archive tmpdir/libstrip.a
444	set objfile tmpdir/testprog.o
445    }
446
447    remote_file build delete tmpdir/libstrip.a
448
449    set exec_output [binutils_run $AR "rc $archive ${objfile}"]
450    if ![string equal "" $exec_output] {
451	fail $test
452	unresolved "$test preserving OS/ABI"
453	return
454    }
455
456    set exec_output [binutils_run $STRIP "-g $archive"]
457    if ![string equal "" $exec_output] {
458	fail $test
459	unresolved "$test preserving OS/ABI"
460	return
461    }
462
463    set exec_output [binutils_run $STRIP "$STRIPFLAGS $archive"]
464    if ![string equal "" $exec_output] {
465	fail $test
466	unresolved "$test preserving OS/ABI"
467	return
468    }
469
470    if { $osabi_fail != "true" && [is_elf_format] } {
471	verbose -log "$READELF -a tmpdir/testprog.o > tmpdir/osabi.out"
472	set exec_output [remote_exec host "$READELF -h tmpdir/testprog.o" "" "/dev/null" "tmpdir/osabi.out"]
473	if { [lindex $exec_output 0] != 0 } then {
474	    unresolved "$test preserving OS/ABI"
475	} else {
476	    verbose -log "grep OS/ABI tmpdir/osabi.out"
477	    catch "exec grep OS/ABI tmpdir/osabi.out" osabi_out
478	    if { "$osabi_in" == "$osabi_out" } {
479		pass "$test preserving OS/ABI"
480	    } else {
481		fail "$test preserving OS/ABI"
482	    }
483	}
484    }
485
486    if { [target_compile $srcdir/$subdir/testprog.c tmpdir/testprog.o object debug] != "" } {
487	untested $test
488	return
489    }
490
491    if [is_remote host] {
492	set objfile [remote_download host tmpdir/testprog.o]
493    } else {
494	set objfile tmpdir/testprog.o
495    }
496
497    set exec_output [binutils_run $STRIP "$STRIPFLAGS $objfile"]
498    if ![string equal "" $exec_output] {
499	fail $test
500	return
501    }
502
503    set exec_output [binutils_run $NM "-a $NMFLAGS $objfile"]
504    if ![string match "*: no symbols*" $exec_output] {
505	fail $test
506	return
507    }
508
509    pass $test
510}
511
512strip_test
513
514# Test stripping an object file with saving a symbol
515
516proc strip_test_with_saving_a_symbol { } {
517    global CC
518    global STRIP
519    global STRIPFLAGS
520    global NM
521    global NMFLAGS
522    global srcdir
523    global subdir
524
525    set test "strip with saving a symbol"
526
527    if { [target_compile $srcdir/$subdir/testprog.c tmpdir/testprog.o object debug] != "" } {
528	untested $test
529	return
530    }
531
532    if [is_remote host] {
533	set objfile [remote_download host tmpdir/testprog.o]
534    } else {
535	set objfile tmpdir/testprog.o
536    }
537
538    set exec_output [binutils_run $STRIP "$STRIPFLAGS -K main -K _main $objfile"]
539    if ![string equal "" $exec_output] {
540	fail $test
541	return
542    }
543
544    set exec_output [binutils_run $NM "$NMFLAGS $objfile"]
545    if {![regexp {^([0-9a-fA-F]+)?[ ]+[TD] main} $exec_output] \
546         && ![regexp {^([0-9a-fA-F]+)?[ ]+T _main} $exec_output]} {
547	fail $test
548	return
549    }
550
551    pass $test
552}
553
554strip_test_with_saving_a_symbol
555
556# Build a final executable.
557
558if { [istarget *-*-cygwin] || [istarget *-*-mingw*] } {
559    set test_prog "testprog.exe"
560} else {
561    set test_prog "testprog"
562}
563
564proc copy_setup { } {
565    global srcdir
566    global subdir
567    global gcc_gas_flag
568    global test_prog
569    global host_triplet
570
571    set res [build_wrapper testglue.o]
572    set flags { debug }
573
574    if { [istarget *-*-uclinux*] && ![istarget tic6x-*-*] } {
575	return 1
576    }
577
578    if { $res != "" } {
579	lappend flags "additional_flags=[lindex $res 1]"
580	set add_libs "testglue.o"
581    } else {
582	set add_libs ""
583    }
584
585    if { [istarget *-*-linux*]
586	 || [istarget *-*-gnu*] } {
587	foreach i $gcc_gas_flag {
588	    set flags "additional_flags=$i $flags"
589	}
590    }
591    if { [target_compile "$srcdir/$subdir/testprog.c $add_libs" tmpdir/$test_prog executable $flags]  != "" } {
592	return 2
593    }
594
595    set result [remote_load target tmpdir/$test_prog]
596    set status [lindex $result 0]
597
598    if { $status != "pass"  } {
599	send_log "cannot run executable, status = ${status} on ${host_triplet}\n"
600	return 3
601    }
602
603    return 0
604}
605
606# Test copying an executable.
607
608proc copy_executable { prog flags test1 test2 } {
609    global test_prog
610
611    if [is_remote host] {
612	set testfile [remote_download host tmpdir/$test_prog]
613	set testcopy copyprog
614    } else {
615	set testfile tmpdir/$test_prog
616	set testcopy tmpdir/copyprog
617    }
618    remote_file host delete $testcopy
619
620    set exec_output [binutils_run $prog "$flags $testfile $testcopy"]
621
622    if ![string equal "" $exec_output] {
623	fail $test1
624	if [string equal "" $test2] {
625	    return
626	}
627	fail $test2
628	return
629    }
630
631    if [is_remote host] {
632	remote_upload host $testcopy tmpdir/copyprog
633    }
634
635    set status [remote_exec build "cmp" "tmpdir/$test_prog tmpdir/copyprog"]
636    set exec_output [lindex $status 1]
637
638    if [string equal "" $exec_output] then {
639	pass $test1
640    } else {
641	send_log "$exec_output\n"
642	verbose "$exec_output"
643
644	# This will fail for many reasons.  For example, it will most
645	# likely fail if a non-GNU linker is used.  Therefore, we do
646	# not insist that it pass.  If you are using an assembler and
647	# linker based on the same BFD as objcopy, it is worth
648	# investigating to see why this failure occurs.  If we are
649	# cross compiling, we assume that a GNU linker is being used,
650	# and expect it to succeed.
651	if {[isnative]} then {
652	    setup_xfail "*-*-*"
653	}
654
655	# This also fails for some mips targets.  See elf32-mips.c
656	# mips_elf_sym_is_global.
657	if { [is_bad_symtab] } then {
658	    setup_xfail "*-*-*"
659	}
660
661	setup_xfail "arm*-*-coff"
662	setup_xfail "arm*-*-pe"
663	setup_xfail "*-*-mingw*"
664	setup_xfail "*-*-cygwin*"
665
666	fail $test1
667    }
668
669    if [string equal "" $test2] {
670	return
671    }
672
673    set output [remote_load target tmpdir/copyprog]
674    set status [lindex $output 0]
675    if { $status != "pass" } {
676	fail $test2
677    } else {
678	pass $test2
679    }
680}
681
682# Test stripping an executable
683
684proc strip_executable { prog flags test1 test2 } {
685    global NM
686    global NMFLAGS
687    global READELF
688
689    remote_file build delete tmpdir/striprog
690    remote_download build tmpdir/copyprog tmpdir/striprog
691    if [is_remote host] {
692	set copyfile [remote_download host tmpdir/striprog]
693    } else {
694	set copyfile tmpdir/striprog
695    }
696
697    set osabi_fail "false"
698    if [is_elf_format] {
699	verbose -log "$READELF -a ${copyfile} > tmpdir/osabi.in"
700	set exec_output [remote_exec host "$READELF -h ${copyfile}" "" "/dev/null" "tmpdir/osabi.in"]
701	if { [lindex $exec_output 0] != 0 } then {
702	    unresolved "$test1 preserving OS/ABI"
703	    set osabi_fail "true"
704	} else {
705	    verbose -log "grep OS/ABI tmpdir/osabi.in"
706	    catch "exec grep OS/ABI tmpdir/osabi.in" osabi_in
707	}
708     }
709
710    set exec_output [binutils_run $prog "$flags ${copyfile}"]
711    if ![string equal "" $exec_output] {
712	fail $test1
713	if [string equal "" $test2] {
714	    return
715	}
716	fail $test2
717	return
718    }
719
720    if [is_remote host] {
721	remote_upload host ${copyfile} tmpdir/striprog
722    }
723
724    if { $osabi_fail != "true" && [is_elf_format] } {
725	verbose -log "$READELF -a ${copyfile} > tmpdir/osabi.out"
726	set exec_output [remote_exec host "$READELF -h ${copyfile}" "" "/dev/null" "tmpdir/osabi.out"]
727	if { [lindex $exec_output 0] != 0 } then {
728	    unresolved "$test1 preserving OS/ABI"
729	} else {
730	    verbose -log "grep OS/ABI tmpdir/osabi.out"
731	    catch "exec grep OS/ABI tmpdir/osabi.out" osabi_out
732	    if { "$osabi_in" == "$osabi_out" } {
733		pass "$test1 preserving OS/ABI"
734	    } else {
735		fail "$test1 preserving OS/ABI"
736	    }
737	}
738    }
739
740    set exec_output [binutils_run $NM "$NMFLAGS ${copyfile}"]
741    if ![string match "*: no symbols*" $exec_output] {
742	fail $test1
743	return
744    }
745
746    if [string equal "" $test2] {
747	return
748    }
749
750    set result [remote_load target tmpdir/striprog]
751    set status [lindex $result 0]
752    if { $status != "pass" } {
753	fail $test2
754        return
755    }
756
757    pass $test2
758}
759
760# Test stripping an executable with saving a symbol
761
762proc strip_executable_with_saving_a_symbol { prog flags test1 test2 } {
763    global NM
764    global NMFLAGS
765
766    remote_file build delete tmpdir/striprog
767    remote_download build tmpdir/copyprog tmpdir/striprog
768    if [is_remote host] {
769	set copyfile [remote_download host tmpdir/striprog]
770    } else {
771	set copyfile tmpdir/striprog
772    }
773
774    set exec_output [binutils_run $prog "$flags ${copyfile}"]
775    if ![string equal "" $exec_output] {
776	fail $test1
777	if [string equal "" $test2] {
778	    return
779	}
780	fail $test2
781	return
782    }
783
784    set exec_output [binutils_run $NM "$NMFLAGS ${copyfile}"]
785    if { [istarget mmix-knuth-mmixware] } {
786	# Whenever there's a symbol in the mmo format, there's the symbol
787	# Main, so remove it manually from the expected output for sake of
788	# this test.
789
790	# Using "" not {} to get the \n and \r translated.
791	regsub "^\[0-9a-fA-F\]+\[ \]+T Main\[\n\r\]+" $exec_output "" exec_output
792    }
793
794    if {![regexp {^([0-9a-fA-F]+)?[ ]+[TD] main} $exec_output] \
795         && ![regexp {^([0-9a-fA-F]+)?[ ]+[TD] _main} $exec_output]} {
796	fail $test1
797	return
798    }
799
800    if [string equal "" $test2] {
801	return
802    }
803
804    if [is_remote host] {
805	remote_upload host ${copyfile} tmpdir/striprog
806    }
807
808    set result [remote_load target tmpdir/striprog]
809    set status [lindex $result 0]
810    if { $status != "pass" } {
811	fail $test2
812        return
813    }
814
815    pass $test2
816}
817
818# Test keeping only debug symbols of an executable
819
820proc keep_debug_symbols_and_test_copy { prog1 flags1 test1 prog2 flags2 test2 } {
821    remote_file build delete tmpdir/striprog
822    remote_download build tmpdir/copyprog tmpdir/striprog
823    if [is_remote host] {
824	set copyfile [remote_download host tmpdir/striprog]
825    } else {
826	set copyfile tmpdir/striprog
827    }
828
829    set exec_output [binutils_run $prog1 "$flags1 ${copyfile}"]
830    if ![string equal "" $exec_output] {
831	fail $test1
832	return
833    }
834    pass $test1
835
836    set exec_output [binutils_run $prog2 "$flags2 ${copyfile}"]
837    if ![string equal "" $exec_output] {
838	fail $test2
839	return
840    }
841    pass $test2
842}
843
844# Tests that in a debug only copy of a file the sections
845# headers whoes types have been changed to NOBITS still
846# retain their sh_link fields.
847
848proc keep_debug_symbols_and_check_links { prog flags test } {
849    global READELF
850
851    remote_file build delete tmpdir/striprog
852    remote_download build tmpdir/copyprog tmpdir/striprog
853    if [is_remote host] {
854	set copyfile [remote_download host tmpdir/striprog]
855    } else {
856	set copyfile tmpdir/striprog
857    }
858
859    set exec_output [binutils_run $prog "$flags ${copyfile}"]
860    if ![string equal "" $exec_output] {
861	fail $test
862	return
863    }
864
865    set got [binutils_run $READELF "-S --wide ${copyfile}"]
866
867    set fails 0
868    # Regexp to match a section with NOBITS type and extract its name and sh_link fields
869    while {[regexp \
870		{[^a-zA-Z]+([a-zA-Z0-9_\.]+)[ 	]+NOBITS[ 	]+[0-9a-fA-F]+ [0-9a-fA-F]+ [0-9a-fA-F]+ [0-9]+[ A]+([0-9]+)(.*)} \
871		$got all name link rest]} {
872	set sh_link 0x$link
873	if {$sh_link == 0} {
874	    # Only some NOBITS sections should have a non-zero sh_link field.
875	    # Look for them by name.
876	    verbose "NOBITS section .$name has a 0 sh_link field\n"
877	    switch $name {
878		"rela.*"	{ set fails 1 ; send_log "Expected non-zero sh_link for .$name\n" }
879		"rel.*"		{ set fails 1 ; send_log "Expected non-zero sh_link for .$name\n" }
880		"hash"		{ set fails 1 ; send_log "Expected non-zero sh_link for .$name\n" }
881		"gnu_version"	{ set fails 1 ; send_log "Expected non-zero sh_link for .$name\n" }
882		"dynsym"	{ set fails 1 ; send_log "Expected non-zero sh_link for .$name\n" }
883		"gnu.version_r"	{ set fails 1 ; send_log "Expected non-zero sh_link for .$name\n" }
884		"dynamic"	{ set fails 1 ; send_log "Expected non-zero sh_link for .$name\n" }
885		"symtab"	{ set fails 1 ; send_log "Expected non-zero sh_link for .$name\n" }
886	    }
887	}
888	set got $rest
889    }
890
891    if {$fails == 0} {
892	pass $test
893    } else {
894	fail $test
895    }
896}
897
898
899set test1 "simple objcopy of executable"
900set test1r "run objcopy of executable"
901set test2 "strip executable"
902set test2r "run stripped executable"
903set test3 "strip executable with saving a symbol"
904set test3r "run stripped executable with saving a symbol"
905set test4 "keep only debug data"
906set test5 "simple objcopy of debug data"
907if [is_elf_format] {
908    set test6 "NOBITS sections retain sh_link field"
909}
910
911switch [copy_setup] {
912    "1" {
913	# do nothing
914    }
915    "2" {
916	untested $test1
917	untested $test1r
918	untested $test2
919	untested $test2r
920	untested $test3
921	untested $test3r
922	untested $test4
923	untested $test5
924	if [is_elf_format] {
925	    untested $test6
926	}
927    }
928    "3" {
929	copy_executable "$OBJCOPY" "$OBJCOPYFLAGS" "$test1" ""
930	unsupported $test1r
931	strip_executable "$STRIP" "$STRIPFLAGS" "$test2" ""
932	unsupported $test2r
933	strip_executable_with_saving_a_symbol "$STRIP" "-K main -K _main $STRIPFLAGS" "$test3" ""
934	unsupported $test3r
935	keep_debug_symbols_and_test_copy "$STRIP" "--only-keep-debug $STRIPFLAGS" "$test4" \
936					 "$OBJCOPY" "$OBJCOPYFLAGS" "$test5"
937	if [is_elf_format] {
938	    keep_debug_symbols_and_check_links "$STRIP" "--only-keep-debug $STRIPFLAGS" "$test6"
939	}
940    }
941    "0" {
942	copy_executable "$OBJCOPY" "$OBJCOPYFLAGS" "$test1" "$test1r"
943	strip_executable "$STRIP" "$STRIPFLAGS" "$test2" "$test2r"
944	strip_executable_with_saving_a_symbol "$STRIP" "-K main -K _main $STRIPFLAGS" "$test3" "$test3r"
945	keep_debug_symbols_and_test_copy "$STRIP" "--only-keep-debug $STRIPFLAGS" "$test4" \
946					 "$OBJCOPY" "$OBJCOPYFLAGS" "$test5"
947	if [is_elf_format] {
948	    keep_debug_symbols_and_check_links "$STRIP" "--only-keep-debug $STRIPFLAGS" "$test6"
949	}
950    }
951}
952
953proc objcopy_test_readelf {testname srcfile} {
954    global OBJCOPY
955    global OBJCOPYFLAGS
956    global READELF
957    global srcdir
958    global subdir
959
960    if {![binutils_assemble $srcdir/$subdir/${srcfile} tmpdir/bintest.o]} then {
961	unresolved "objcopy ($testname)"
962	return
963    }
964
965    verbose -log "$OBJCOPY $OBJCOPYFLAGS tmpdir/bintest.o tmpdir/copy.o"
966    set exec_output [remote_exec host "$OBJCOPY $OBJCOPYFLAGS tmpdir/bintest.o tmpdir/copy.o"]
967    if { [lindex $exec_output 0] != 0
968	 || ![string equal "" [lindex $exec_output 1]] } then {
969	fail "objcopy ($testname)"
970	return
971    }
972
973    verbose -log "$READELF -a tmpdir/bintest.o > tmpdir/bintest.o.out"
974    set exec_output [remote_exec host "$READELF -a tmpdir/bintest.o" "" "/dev/null" "tmpdir/bintest.o.out"]
975    if { [lindex $exec_output 0] != 0 } then {
976	unresolved "objcopy ($testname)"
977	return
978    }
979    set exec_output [prune_warnings [lindex $exec_output 1]]
980    if ![string equal "" $exec_output] then {
981	unresolved "objcopy ($testname)"
982	return
983    }
984
985    verbose -log "$READELF -a tmpdir/copy.o > tmpdir/copy.o.out"
986    set exec_output [remote_exec host "$READELF -a tmpdir/copy.o" "" "/dev/null" "tmpdir/copy.o.out"]
987    if { [lindex $exec_output 0] != 0 } then {
988	unresolved "objcopy ($testname)"
989	return
990    }
991    set exec_output [prune_warnings [lindex $exec_output 1]]
992    if ![string equal "" $exec_output] then {
993	unresolved "objcopy ($testname)"
994	return
995    }
996
997    verbose -log "diff tmpdir/bintest.o.out tmpdir/copy.o.out"
998    catch "exec diff tmpdir/bintest.o.out tmpdir/copy.o.out" exec_output
999    set exec_output [prune_warnings $exec_output]
1000
1001    if [string equal "" $exec_output] then {
1002	pass "objcopy ($testname)"
1003    } else {
1004	fail "objcopy ($testname)"
1005    }
1006}
1007
1008proc objcopy_test_symbol_manipulation {} {
1009    global srcdir
1010    global subdir
1011
1012    set test_list [lsort [glob -nocomplain $srcdir/$subdir/symbols-*.d]]
1013    foreach t $test_list {
1014        # We need to strip the ".d", but can leave the dirname.
1015        verbose [file rootname $t]
1016        run_dump_test [file rootname $t]
1017    }
1018}
1019
1020proc objcopy_test_elf_common_symbols {} {
1021    global srcdir
1022    global subdir
1023
1024    # hpux has a non-standard common directive.
1025    if { [istarget "*-*-hpux*"] } then {
1026	return
1027    }
1028
1029    set test_list [lsort [glob -nocomplain $srcdir/$subdir/common-*.d]]
1030    foreach t $test_list {
1031        # We need to strip the ".d", but can leave the dirname.
1032        verbose [file rootname $t]
1033        run_dump_test [file rootname $t]
1034    }
1035}
1036
1037# ia64 specific tests
1038if { ([istarget "ia64-*-elf*"]
1039       || [istarget "ia64-*-linux*"]) } {
1040    objcopy_test "ia64 link order" link-order.s
1041}
1042
1043# ELF specific tests
1044if [is_elf_format] {
1045    objcopy_test_symbol_manipulation
1046    objcopy_test_elf_common_symbols
1047    objcopy_test "ELF unknown section type" unknown.s
1048    objcopy_test_readelf "ELF group" group.s
1049    objcopy_test_readelf "ELF group" group-2.s
1050    objcopy_test_readelf "ELF group" group-3.s
1051    objcopy_test_readelf "ELF group" group-4.s
1052    run_dump_test "group-5"
1053    run_dump_test "group-6"
1054    run_dump_test "copy-1"
1055    run_dump_test "note-1"
1056}
1057
1058run_dump_test "copy-2"
1059run_dump_test "copy-3"
1060run_dump_test "copy-4"
1061run_dump_test "pr19020a"
1062run_dump_test "pr19020b"
1063
1064if [is_elf_format] {
1065    run_dump_test "strip-1"
1066    run_dump_test "strip-2"
1067    run_dump_test "strip-3"
1068    run_dump_test "strip-4"
1069    run_dump_test "strip-5"
1070    run_dump_test "strip-6"
1071    run_dump_test "strip-7"
1072    run_dump_test "strip-8"
1073    run_dump_test "strip-9"
1074    run_dump_test "strip-12"
1075    # This requires STB_GNU_UNIQUE support with OSABI set to GNU.
1076    if { [supports_gnu_unique] } {
1077	run_dump_test "strip-10"
1078    }
1079    set extra_strip11 ""
1080    if { [istarget "sh64*-*"] } {
1081	# pr17755 testcase
1082	set extra_strip11 { { "as" "--isa=SHmedia --abi=64" } }
1083    }
1084    run_dump_test "strip-11" $extra_strip11
1085
1086    if { [istarget "i*86-*"] || [istarget "x86_64-*-*"] } {
1087	# Check to make sure we don't strip a symbol named in relocations.
1088	set test "objcopy keeps symbols needed by relocs"
1089
1090	set srcfile $srcdir/$subdir/needed-by-reloc.s
1091
1092	if {![binutils_assemble $srcfile tmpdir/bintest.o]} then {
1093	    unresolved $test
1094	} else {
1095	    set got [binutils_run $OBJCOPY "$OBJCOPYFLAGS --strip-symbol=foo tmpdir/bintest.o ${copyfile}.o"]
1096
1097	    if [regexp "not stripping symbol `foo' because it is named in a relocation" $got] {
1098		pass $test
1099	    } else {
1100		fail $test
1101	    }
1102	}
1103    }
1104
1105    # The symbol table for some MIPS targets is sorted differently than
1106    # the ELF canonical order, so the regexps in localize-hidden-1.d fail
1107    # to match.
1108    if { [is_bad_symtab] } then {
1109	setup_xfail "*-*-*"
1110    }
1111    run_dump_test "localize-hidden-1"
1112    run_dump_test "testranges"
1113    run_dump_test "testranges-ia64"
1114
1115    run_dump_test "add-section"
1116    run_dump_test "add-symbol"
1117    run_dump_test "add-empty-section"
1118
1119    run_dump_test "exclude-1a"
1120    run_dump_test "exclude-1b"
1121}
1122run_dump_test "localize-hidden-2"
1123
1124# Test objcopying an object file without global symbol
1125
1126proc objcopy_test_without_global_symbol { } {
1127    global OBJCOPY
1128    global OBJCOPYFLAGS
1129    global OBJDUMP
1130    global OBJDUMPFLAGS
1131    global srcdir
1132    global subdir
1133
1134    set test "strip without global symbol "
1135
1136    if { [target_compile $srcdir/$subdir/pr19547.c tmpdir/pr19547.o object debug] != "" } {
1137	untested $test
1138	return
1139    }
1140
1141    if [is_remote host] {
1142	set objfile [remote_download host tmpdir/pr19547.o]
1143    } else {
1144	set objfile tmpdir/pr19547.o
1145    }
1146
1147    set exec_output [binutils_run $OBJCOPY "$OBJCOPYFLAGS --strip-unneeded $objfile"]
1148    if ![string equal "" $exec_output] {
1149	fail $test
1150	return
1151    }
1152
1153    set exec_output [binutils_run $OBJDUMP "$OBJDUMPFLAGS -t $objfile"]
1154    if {![regexp "no symbols" $exec_output]} {
1155	fail $test
1156	return
1157    }
1158
1159    pass $test
1160}
1161
1162# The AArch64 and ARM targets preserve mapping symbols
1163# in object files, so they will fail this test.
1164setup_xfail aarch64*-*-* arm*-*-*
1165
1166objcopy_test_without_global_symbol
1167