1# Copyright (C) 1993-2016 Free Software Foundation, Inc.
2#
3# This file is part of the GNU Binutils.
4#
5# This file 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 3 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,
18# MA 02110-1301, USA.
19
20# True if the object format is known to be ELF.
21#
22proc is_elf_format {} {
23    # config.sub for these targets curiously transforms a target doublet
24    # ending in -elf to -none.  eg. m68hc12-elf to m68hc12-unknown-none
25    # They are always elf.
26    if { [istarget m68hc1*-*] || [istarget xgate-*] } {
27	return 1;
28    }
29
30    if {    ![istarget *-*-eabi*]
31	 && ![istarget *-*-elf*]
32	 && ![istarget *-*-freebsd*]
33	 && ![istarget *-*-gnu*]
34	 && ![istarget *-*-irix5*]
35	 && ![istarget *-*-irix6*]
36	 && ![istarget *-*-linux*]
37	 && ![istarget *-*-nacl*]
38	 && ![istarget *-*-netbsd*]
39	 && ![istarget *-*-openbsd*]
40	 && ![istarget *-*-rtems*]
41	 && ![istarget *-*-solaris2*]
42	 && ![istarget *-*-sysv4*]
43	 && ![istarget *-*-unixware*]
44	 && ![istarget avr-*-*]
45	 && ![istarget bfin-*-uclinux]
46	 && ![istarget frv-*-uclinux*]
47	 && ![istarget hppa*64*-*-hpux*]
48	 && ![istarget ia64-*-hpux*]
49	 && ![istarget sh*-*-uclinux*]
50	 && ![istarget tic6x*-*-uclinux*] } {
51	return 0
52    }
53
54    if {    [istarget *-*-linux*aout*]
55	 || [istarget *-*-linux*ecoff*]
56	 || [istarget *-*-linux*oldld*]
57	 || [istarget *-*-rtemscoff*]
58	 || [istarget h8500-*-rtems*]
59	 || [istarget i?86-*-freebsd\[12\].*]
60	 || [istarget i960-*-rtems*] } {
61	return 0
62    }
63
64    if { ![istarget *-*-netbsdelf*]
65	 && (   [istarget *-*-netbsd*aout*]
66	     || [istarget *-*-netbsdpe*]
67	     || [istarget arm*-*-netbsd*]
68	     || [istarget sparc-*-netbsd*]
69	     || [istarget i*86-*-netbsd*]
70	     || [istarget m68*-*-netbsd*]
71	     || [istarget vax-*-netbsd*]
72	     || [istarget ns32k-*-netbsd*]) } {
73    	return 0
74    }
75
76    if {    [istarget arm-*-openbsd*]
77	 || [istarget i386-*-openbsd\[0-2\].*]
78	 || [istarget i386-*-openbsd3.\[0-2\]]
79	 || [istarget m68*-*-openbsd*]
80	 || [istarget ns32k-*-openbsd*]
81	 || [istarget sparc-*-openbsd\[0-2\].*]
82	 || [istarget sparc-*-openbsd3.\[0-1\]]
83	 || [istarget vax-*-openbsd*] } {
84	return 0
85    }
86
87    return 1
88}
89
90# True if the object format is known to be a.out.
91#
92proc is_aout_format {} {
93    if { [istarget *-*-netbsdelf]
94	 || [istarget sparc64-*-netbsd*]
95	 || [istarget sparc64-*-openbsd*] } {
96	return 0
97    }
98    if { [istarget *-*-*\[ab\]out*]
99	 || [istarget *-*-linux*oldld*]
100	 || [istarget *-*-bsd*]
101	 || [istarget *-*-msdos*]
102	 || [istarget arm-*-netbsd*]
103	 || [istarget arm-*-openbsd*]
104	 || [istarget arm-*-riscix*]
105	 || [istarget i?86-*-freebsd\[12\].*]
106	 || [istarget i?86-*-netbsd*]
107	 || [istarget i?86-*-openbsd\[0-2\]*]
108	 || [istarget i?86-*-openbsd3.\[0-2\]*]
109	 || [istarget i?86-*-vsta]
110	 || [istarget i?86-*-mach*]
111	 || [istarget m68*-*-netbsd*]
112	 || [istarget m68*-*-openbsd*]
113	 || [istarget ns32k-*-*]
114	 || [istarget pdp11-*-*]
115	 || [istarget sparc*-*-sunos4*]
116	 || [istarget sparc*-*-netbsd*]
117	 || [istarget sparc*-*-openbsd\[0-2\]*]
118	 || [istarget sparc*-*-openbsd3.\[0-1\]*]
119	 || [istarget sparc*-fujitsu-none]
120	 || [istarget vax-dec-ultrix*]
121	 || [istarget vax-*-netbsd] } {
122	return 1
123    }
124    return 0
125}
126
127# True if the object format is known to be PE COFF.
128#
129proc is_pecoff_format {} {
130    if { ![istarget *-*-mingw*]
131	 && ![istarget *-*-cygwin*]
132	 && ![istarget *-*-cegcc*]
133	 && ![istarget *-*-pe*] } {
134	return 0
135    }
136
137    return 1
138}
139
140# True if the object format is known to be 64-bit ELF.
141#
142proc is_elf64 { binary_file } {
143    global READELF
144    global READELFFLAGS
145
146    set readelf_size ""
147    catch "exec $READELF $READELFFLAGS -h $binary_file > readelf.out" got
148
149    if ![string match "" $got] then {
150	return 0
151    }
152
153    if { ![regexp "\n\[ \]*Class:\[ \]*ELF(\[0-9\]+)\n" \
154	   [file_contents readelf.out] nil readelf_size] } {
155	return 0
156    }
157
158    if { $readelf_size == "64" } {
159	return 1
160    }
161
162    return 0
163}
164
165# True if the ELF target supports STB_GNU_UNIQUE with the ELF header's
166# OSABI field set to ELFOSABI_GNU.
167#
168# This generally depends on the target OS only, however there are a
169# number of exceptions for bare metal targets as follows.  The MSP430
170# and Visium targets set OSABI to ELFOSABI_STANDALONE and cannot
171# support STB_GNU_UNIQUE.  Likewise non-EABI ARM targets set OSABI to
172# ELFOSABI_ARM, and TI C6X targets to ELFOSABI_C6000_*.  Finally
173# rather than `bfd_elf_final_link' AM33/2.0, D30V, DLX, i960, and
174# picoJava targets use `_bfd_generic_final_link', which does not
175# support STB_GNU_UNIQUE symbol binding causing assertion failures.
176#
177proc supports_gnu_unique {} {
178    if { [istarget *-*-gnu*]
179	 || [istarget *-*-linux*]
180	 || [istarget *-*-nacl*] } {
181	return 1
182    }
183    if { [istarget "arm*-*-*eabi*"] } {
184	return 1
185    }
186    if { ![istarget "*-*-elf*"] } {
187	return 0
188    }
189    if { [istarget "arm*-*-*"]
190	 || [istarget "msp430-*-*"]
191	 || [istarget "tic6x-*-*"]
192	 || [istarget "visium-*-*"] } {
193	return 0
194    }
195    if { [istarget "am33_2.0-*-*"]
196	 || [istarget "d30v-*-*"]
197	 || [istarget "dlx-*-*"]
198	 || [istarget "i960-*-*"]
199	 || [istarget "pj*-*-*"] } {
200	return 0
201    }
202    return 1
203}
204
205# True for targets that do not sort .symtab as per the ELF standard.
206# ie. any that have mips_elf32_be_vec, mips_elf32_le_vec,
207# mips_elf32_n_be_vec or mips_elf32_n_le_vec as the primary bfd target
208# vector in config.bfd.  When syncing with config.bfd, don't forget that
209# earlier case-matches trump later ones.
210proc is_bad_symtab {} {
211    if { ![istarget "mips*-*-*"] } {
212	return 0;
213    }
214    if { [istarget "*-*-chorus*"]
215	 || [istarget "*-*-irix5*"]
216	 || [istarget "*-*-irix6*"]
217	 || [istarget "*-*-none"]
218	 || [istarget "*-*-rtems*"]
219	 || [istarget "*-*-windiss"] } {
220	return 1;
221    }
222    if { [istarget "*-*-elf*"]
223	 && ![istarget "*-sde-*"]
224	 && ![istarget "*-mti-*"]
225	 && ![istarget "*-img-*"] } {
226	return 1;
227    }
228    if { [istarget "*-*-openbsd*"]
229	 && ![istarget "mips64*-*-*"] } {
230	return 1;
231    }
232    return 0;
233}
234
235# Compare two files line-by-line.  FILE_1 is the actual output and FILE_2
236# is the expected output.  Ignore blank lines in either file.
237#
238# FILE_2 is a series of regexps, comments and # directives.  The directives
239# are:
240#
241#    #pass
242#        Treat the test as a PASS if everything up till this point has
243#        matched.  Ignore any remaining lines in either FILE_1 or FILE_2.
244#
245#    #failif
246#        Reverse the sense of the test: expect differences to exist.
247#
248#    #...
249#    REGEXP
250#        Skip all lines in FILE_1 until the first that matches REGEXP.
251#
252# Other # lines are comments.  Regexp lines starting with the `!' character
253# specify inverse matching (use `\!' for literal matching against a leading
254# `!').  Skip empty lines in both files.
255#
256# The first optional argument is a list of regexp substitutions of the form:
257#
258#    EXP1 SUBSPEC1 EXP2 SUBSPEC2 ...
259#
260# This tells the function to apply each regexp substitution EXPi->SUBSPECi
261# in order to every line of FILE_2.
262#
263# Return nonzero if differences exist.
264proc regexp_diff { file_1 file_2 args } {
265    set eof -1
266    set end_1 0
267    set end_2 0
268    set differences 0
269    set diff_pass 0
270    set fail_if_match 0
271    set ref_subst ""
272    if { [llength $args] > 0 } {
273	set ref_subst [lindex $args 0]
274    }
275    if { [llength $args] > 1 } {
276	perror "Too many arguments to regexp_diff"
277	return 1
278    }
279
280    if [file exists $file_1] then {
281	set file_a [open $file_1 r]
282    } else {
283	perror "$file_1 doesn't exist"
284	return 1
285    }
286
287    if [file exists $file_2] then {
288	set file_b [open $file_2 r]
289    } else {
290	perror "$file_2 doesn't exist"
291	close $file_a
292	return 1
293    }
294
295    verbose " Regexp-diff'ing: $file_1 $file_2" 2
296
297    while { 1 } {
298	set line_a ""
299	set line_b ""
300	while { [string length $line_a] == 0 } {
301	    # Ignore blank line in FILE_1.
302	    if { [gets $file_a line_a] == $eof } {
303		set end_1 1
304		break
305	    }
306	}
307	while { [string length $line_b] == 0 || [string match "#*" $line_b] } {
308	    if { [string match "#pass" $line_b] } {
309		set end_2 1
310		set diff_pass 1
311		break
312	    } elseif { [string match "#failif" $line_b] } {
313		send_log "fail if no difference\n"
314		verbose "fail if no difference" 3
315		set fail_if_match 1
316	    } elseif { [string match "#..." $line_b] } {
317		if { [gets $file_b line_b] == $eof } {
318		    set end_2 1
319		    set diff_pass 1
320		    break
321		}
322		set negated [expr { [string index $line_b 0] == "!" }]
323		set line_bx [string range $line_b $negated end]
324		set n [expr { $negated ? "! " : "" }]
325		# Substitute on the reference.
326		foreach {name value} $ref_subst {
327		    regsub -- $name $line_bx $value line_bx
328		}
329		verbose "looking for $n\"^$line_bx$\"" 3
330		while { [expr [regexp "^$line_bx$" "$line_a"] == $negated] } {
331		    verbose "skipping    \"$line_a\"" 3
332		    if { [gets $file_a line_a] == $eof } {
333			set end_1 1
334			break
335		    }
336		}
337		break
338	    }
339	    if { [gets $file_b line_b] == $eof } {
340		set end_2 1
341		break
342	    }
343	}
344
345	if { $diff_pass } {
346	    break
347	} elseif { $end_1 && $end_2 } {
348	    break
349	} elseif { $end_1 } {
350	    send_log "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1\n"
351	    verbose "extra regexps in $file_2 starting with \"^$line_b$\"\nEOF from $file_1" 3
352	    set differences 1
353	    break
354	} elseif { $end_2 } {
355	    send_log "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n"
356	    verbose "extra lines in $file_1 starting with \"^$line_a$\"\nEOF from $file_2\n" 3
357	    set differences 1
358	    break
359	} else {
360	    set negated [expr { [string index $line_b 0] == "!" }]
361	    set line_bx [string range $line_b $negated end]
362	    set n [expr { $negated ? "! " : "" }]
363	    set s [expr { $negated ? "  " : "" }]
364	    # Substitute on the reference.
365	    foreach {name value} $ref_subst {
366		regsub -- $name $line_bx $value line_bx
367	    }
368	    verbose "regexp $n\"^$line_bx$\"\nline   \"$line_a\"" 3
369	    if { [expr [regexp "^$line_bx$" "$line_a"] == $negated] } {
370		send_log "regexp_diff match failure\n"
371		send_log "regexp $n\"^$line_bx$\"\nline   $s\"$line_a\"\n"
372		verbose "regexp_diff match failure\n" 3
373		set differences 1
374	    }
375	}
376    }
377
378    if { $differences == 0 && !$diff_pass && [eof $file_a] != [eof $file_b] } {
379	send_log "$file_1 and $file_2 are different lengths\n"
380	verbose "$file_1 and $file_2 are different lengths" 3
381	set differences 1
382    }
383
384    if { $fail_if_match } {
385	if { $differences == 0 } {
386	    set differences 1
387	} else {
388	    set differences 0
389	}
390    }
391
392    close $file_a
393    close $file_b
394
395    return $differences
396}
397