1# Test basic linker script functionality
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
22set testname "script"
23
24if ![ld_assemble $as $srcdir/$subdir/script.s tmpdir/script.o] {
25    unresolved $testname
26    return
27}
28
29proc check_script { } {
30    global nm
31    global testname
32    global nm_output
33
34    if ![ld_nm $nm "" tmpdir/script] {
35	unresolved $testname
36	return
37    }
38
39    if {![info exists nm_output(text_start)] \
40	    || ![info exists nm_output(text_end)] \
41	    || ![info exists nm_output(data_start)] \
42	    || ![info exists nm_output(data_end)]} {
43	send_log "bad output from nm\n"
44	verbose "bad output from nm"
45	fail $testname
46	return
47    }
48
49    set passes 1
50    set text_end 0x104
51    set data_end 0x1004
52
53    if [istarget *c4x*-*-*] then {
54	set text_end 0x101
55	set data_end 0x1001
56    }
57
58    if [istarget *c54x*-*-*] then {
59	set text_end 0x102
60	set data_end 0x1002
61    }
62
63    if {$nm_output(text_start) != 0x100} {
64	send_log "text_start == $nm_output(text_start)\n"
65	verbose "text_start == $nm_output(text_start)"
66	set passes 0
67    }
68
69    if {[info exists nm_output(tred)] \
70        && $nm_output(tred) != (0x100 + 0x8000)} {
71	send_log "tred == $nm_output(tred)\n"
72	verbose "tred == $nm_output(tred)"
73	set passes 0
74    }
75
76    if {$nm_output(text_end) < $text_end \
77	    || $nm_output(text_end) > 0x110} {
78	send_log "text_end == $nm_output(text_end)\n"
79	verbose "text_end == $nm_output(text_end)"
80	set passes 0
81    }
82
83    if {$nm_output(data_start) != 0x1000} {
84	send_log "data_start == $nm_output(data_start)\n"
85	verbose "data_start == $nm_output(data_start)"
86	set passes 0
87    }
88
89    if {[info exists nm_output(fred)] \
90        && $nm_output(fred) != (0x1000 + 0x10000)} {
91	send_log "fred == $nm_output(fred)\n"
92	verbose "fred == $nm_output(fred)"
93	set passes 0
94    }
95
96    if {$nm_output(data_end) < $data_end \
97	    || $nm_output(data_end) > 0x1010} {
98	send_log "data_end == $nm_output(data_end)\n"
99	verbose "data_end == $nm_output(data_end)"
100	set passes 0
101    }
102
103    if { $passes } {
104	pass $testname
105    } else {
106	fail $testname
107    }
108}
109
110proc extract_symbol_test { testfile testname } {
111    global objcopy
112    global nm
113    global size
114    global target_triplet
115
116    set copyfile tmpdir/extract
117    set args "--extract-symbol $testfile $copyfile"
118    set exec_output [run_host_cmd $objcopy $args]
119    if ![string equal "" $exec_output] {
120	fail $testname
121	return
122    }
123
124    set orig_syms [run_host_cmd $nm $testfile]
125    set syms_massaged $orig_syms
126    switch -regexp $target_triplet {
127	^mmix-knuth-mmixware$ {
128	    # Without section sizes (stripped together with the
129	    # contents for this target), we can't deduce the symbol
130	    # types.  Artificially tracking the symbol types is
131	    # considered not worthwhile as there's no known use-case
132	    # for --extract-symbols for this target.  The option is
133	    # supported just enough to emit the same symbol values,
134	    # but absolute symbol types are expected.
135	    regsub -all " \[TD\] " $syms_massaged " A " syms_massaged
136	}
137	^mips-*-* {
138	    # This test cannot proceed any further for MIPS targets.
139	    # The extract_syms operation produces a binary with a zero
140	    # length .reginfo section, which is illegal under the MIPS
141	    # ABI.  Since producing such sections is part of the expected
142	    # behaviour of --extract-symbols, no further testing can be
143	    # performed.  Fortunately this should not matter as extracting
144	    # symbols is only needed for VxWorks support.
145	    pass $testname
146	    return
147	}
148	[a-z]*-*-pe$ {
149	    # Fails for PE based targets because the extracted section
150	    # relative symbols (eg tred or .text) all become undefined
151	    # when the sections are blown away by --extract-symbol.  Again
152	    # this should not matter as --extract-symbol is only used by
153	    # VxWorks.
154	    pass $testname
155	    return
156	}
157	# More PE variations...
158	[a-z]*-*-mingw* {
159	    pass $testname
160	    return
161	}
162	[a-z]*-*-cygwin$ {
163	    pass $testname
164	    return
165	}
166    }
167
168    set extract_syms [run_host_cmd $nm $copyfile]
169    if ![string equal $syms_massaged $extract_syms] {
170	fail $testname
171	return
172    }
173
174    # Check that the stripped section contains no code or data.
175    set exec_output [run_host_cmd $size $copyfile]
176    if ![regexp ".* 0\[	 \]+0\[	 \]+0\[	 \]+0\[	 \]+0\[	 \]+.*" $exec_output] {
177	fail $testname
178	return
179    }
180
181    pass $testname
182}
183
184# PE targets need to set the image base to 0 to avoid complications from nm.
185set flags ""
186if {[istarget "*-*-pe*"] \
187    || [istarget "*-*-cygwin*"] \
188    || [istarget "*-*-mingw*"] \
189    || [istarget "*-*-winnt*"] \
190    || [istarget "*-*-nt"] \
191    || [istarget "*-*-interix*"] } then {
192  set flags "--image-base 0"
193}
194
195if ![ld_simple_link $ld tmpdir/script "$flags -T $srcdir/$subdir/script.t tmpdir/script.o"] {
196    fail $testname
197} else {
198    check_script
199}
200
201set testname "MRI script"
202
203if ![ld_simple_link $ld tmpdir/script "$flags -c $srcdir/$subdir/scriptm.t"] {
204    fail $testname
205} else {
206    check_script
207}
208
209set testname "MEMORY"
210
211if ![ld_simple_link $ld tmpdir/script "$flags -T $srcdir/$subdir/memory.t tmpdir/script.o"] {
212    fail $testname
213} else {
214    check_script
215}
216
217set testname "MEMORY with symbols"
218if ![ld_simple_link $ld tmpdir/script "$flags -defsym DATA_ORIGIN=0x1000 -defsym DATA_LENGTH=0x10000 -T $srcdir/$subdir/memory_sym.t tmpdir/script.o"] {
219    fail $testname
220    untested "extract symbols"
221} else {
222    check_script
223    extract_symbol_test tmpdir/script "extract symbols"
224}
225
226set test_script_list [lsort [glob $srcdir/$subdir/region-alias-*.t]]
227
228foreach test_script $test_script_list {
229    run_dump_test [string range $test_script 0 end-2]
230}
231
232run_dump_test "align-with-input"
233run_dump_test "pr20302"
234