Commit | Line | Data |
---|---|---|
42a4f53d | 1 | # Copyright (C) 2010-2019 Free Software Foundation, Inc. |
5e3b36f8 JK |
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, see <http://www.gnu.org/licenses/>. | |
15 | ||
16 | # Return nul-terminated string read from section SECTION of EXEC. Return "" | |
17 | # if no such section or nul-terminated string was found. Function is useful | |
18 | # for sections ".interp" or ".gnu_debuglink". | |
19 | ||
20 | proc section_get {exec section} { | |
5e3b36f8 | 21 | global subdir |
53e981d9 | 22 | set tmp [standard_output_file section_get.tmp] |
4fa7d390 | 23 | set objcopy_program [gdb_find_objcopy] |
5e3b36f8 JK |
24 | |
25 | set command "exec $objcopy_program -O binary --set-section-flags $section=A --change-section-address $section=0 -j $section $exec $tmp" | |
26 | verbose -log "command is $command" | |
27 | set result [catch $command output] | |
28 | verbose -log "result is $result" | |
29 | verbose -log "output is $output" | |
30 | if {$result == 1} { | |
31 | return "" | |
32 | } | |
33 | set fi [open $tmp] | |
34 | fconfigure $fi -translation binary | |
35 | set data [read $fi] | |
36 | close $fi | |
37 | file delete $tmp | |
38 | # .interp has size $len + 1 but .gnu_debuglink contains garbage after \000. | |
39 | set len [string first \000 $data] | |
40 | if {$len < 0} { | |
41 | verbose -log "section $section not found" | |
42 | return "" | |
43 | } | |
44 | set retval [string range $data 0 [expr $len - 1]] | |
45 | verbose -log "section $section is <$retval>" | |
46 | return $retval | |
47 | } | |
48 | ||
49 | # Resolve symlinks. | |
50 | ||
51 | proc symlink_resolve {file} { | |
52 | set loop 0 | |
53 | while {[file type $file] == "link"} { | |
54 | set target [file readlink $file] | |
55 | if {[file pathtype $target] == "relative"} { | |
56 | set src2 [file dirname $file]/$target | |
57 | } else { | |
58 | set src2 $target | |
59 | } | |
60 | verbose -log "Resolved symlink $file targetting $target as $src2" | |
61 | set file $src2 | |
62 | ||
63 | set loop [expr $loop + 1] | |
64 | if {$loop > 30} { | |
bc6c7af4 | 65 | fail "looping symlink resolution for $file" |
5e3b36f8 JK |
66 | return "" |
67 | } | |
68 | } | |
69 | return $file | |
70 | } | |
71 | ||
72 | # Copy SRC to DEST, resolving any symlinks in SRC. Return nonzero iff | |
73 | # the copy was succesful. | |
74 | # | |
75 | # This function is guaranteed to never raise any exception, even when the copy | |
76 | # fails. | |
77 | ||
78 | proc file_copy {src dest} { | |
79 | set src [symlink_resolve $src] | |
80 | # Test name would contain unstable directory name for symlink-unresolved | |
81 | # $src. | |
82 | set test "copy [file tail $src] to [file tail $dest]" | |
83 | set command "file copy -force -- $src $dest" | |
84 | verbose -log "command is $command" | |
85 | if [catch $command] { | |
86 | fail $test | |
87 | return 0 | |
88 | } else { | |
89 | pass $test | |
90 | return 1 | |
91 | } | |
92 | } | |
93 | ||
94 | # Wrap function build_executable so that the resulting executable is fully | |
95 | # self-sufficient (without dependencies on system libraries). Parameter | |
96 | # INTERP may be used to specify a loader (ld.so) to be used that is | |
a29a3fb7 GB |
97 | # different from the default system one. INTERP can be set to "no" if no ld.so |
98 | # copy should be made. Libraries on which the executable depends are copied | |
99 | # into directory DIR. Default DIR value to | |
5e3b36f8 JK |
100 | # `${objdir}/${subdir}/${EXECUTABLE}.d'. |
101 | # | |
102 | # In case of success, return a string containing the arguments to be used | |
103 | # in order to perform a prelink of the executable obtained. Return the | |
104 | # empty string in case of failure. | |
105 | # | |
106 | # This can be useful when trying to prelink an executable which might | |
107 | # depend on system libraries. To properly prelink an executable, all | |
108 | # of its dynamically linked libraries must be prelinked as well. If | |
109 | # the executable depends on some system libraries, we may not have | |
110 | # sufficient write priviledges on these files to perform the prelink. | |
111 | # This is why we make a copy of these shared libraries, and link the | |
112 | # executable against these copies instead. | |
113 | # | |
114 | # Function recognizes only libraries listed by `ldd' after | |
115 | # its ` => ' separator. That means $INTERP and any libraries not being linked | |
116 | # with -Wl,-soname,NAME.so are not copied. | |
117 | ||
118 | proc build_executable_own_libs {testname executable sources options {interp ""} {dir ""}} { | |
53e981d9 | 119 | global subdir |
5e3b36f8 | 120 | |
6a5f3f43 YQ |
121 | if { ![isnative] } { |
122 | error "This proc can be only used for native target." | |
123 | } | |
124 | ||
5e3b36f8 JK |
125 | if {[build_executable $testname $executable $sources $options] == -1} { |
126 | return "" | |
127 | } | |
53e981d9 | 128 | set binfile [standard_output_file ${executable}] |
5e3b36f8 | 129 | |
f61d5529 DE |
130 | set ldd [gdb_find_ldd] |
131 | set command "$ldd $binfile" | |
5e3b36f8 JK |
132 | set test "ldd $executable" |
133 | set result [catch "exec $command" output] | |
134 | verbose -log "result of $command is $result" | |
135 | verbose -log "output of $command is $output" | |
136 | if {$result != 0 || $output == ""} { | |
137 | fail $test | |
138 | } else { | |
139 | pass $test | |
140 | } | |
141 | ||
142 | # gdb testsuite will put there also needless -lm. | |
143 | set test "$test output contains libs" | |
144 | set libs [regexp -all -inline -line {^.* => (/[^ ]+).*$} $output] | |
145 | if {[llength $libs] == 0} { | |
146 | fail $test | |
147 | } else { | |
148 | pass $test | |
149 | } | |
150 | ||
151 | if {$dir == ""} { | |
152 | set dir ${binfile}.d | |
153 | } | |
154 | file delete -force -- $dir | |
155 | file mkdir $dir | |
156 | ||
157 | if {$interp == ""} { | |
158 | set interp_system [section_get $binfile .interp] | |
a29a3fb7 GB |
159 | if {$interp_system == ""} { |
160 | fail "$test could not find .interp" | |
161 | } else { | |
162 | set interp ${dir}/[file tail $interp_system] | |
163 | file_copy $interp_system $interp | |
164 | } | |
165 | } | |
166 | if {$interp == "no"} { | |
167 | set interp "" | |
5e3b36f8 JK |
168 | } |
169 | ||
170 | set dests {} | |
171 | foreach {trash abspath} $libs { | |
172 | set dest "$dir/[file tail $abspath]" | |
173 | file_copy $abspath $dest | |
174 | lappend dests $dest | |
175 | } | |
176 | ||
177 | # Do not lappend it so that "-rpath $dir" overrides any possible "-rpath"s | |
178 | # specified by the caller to be able to link it for ldd" above. | |
a29a3fb7 GB |
179 | set options [linsert $options 0 "ldflags=-Wl,-rpath,$dir"] |
180 | if {$interp != ""} { | |
181 | set options [linsert $options 0 "ldflags=-Wl,--dynamic-linker,$interp"] | |
182 | } | |
5e3b36f8 JK |
183 | |
184 | if {[build_executable $testname $executable $sources $options] == -1} { | |
185 | return "" | |
186 | } | |
187 | ||
a29a3fb7 GB |
188 | set prelink_args "--ld-library-path=$dir $binfile [concat $dests]" |
189 | if {$interp != ""} { | |
190 | set prelink_args "--dynamic-linker=$interp $prelink_args $interp" | |
191 | } | |
5e3b36f8 JK |
192 | return $prelink_args |
193 | } | |
194 | ||
195 | # Unprelink ARG. Reported test name can be specified by NAME. Return non-zero | |
196 | # on success, zero on failure. | |
197 | ||
198 | proc prelink_no {arg {name {}}} { | |
199 | if {$name == ""} { | |
200 | set name [file tail $arg] | |
201 | } | |
202 | set test "unprelink $name" | |
203 | set command "exec /usr/sbin/prelink -uN $arg" | |
204 | verbose -log "command is $command" | |
205 | set result [catch $command output] | |
206 | verbose -log "result is $result" | |
207 | verbose -log "output is $output" | |
1a219cc7 JK |
208 | if {$result == 1 && [regexp {^(couldn't execute "/usr/sbin/prelink[^\r\n]*": no such file or directory\n?)*$} $output]} { |
209 | # Without prelink, at least verify that all the binaries do not | |
210 | # contain the ".gnu.prelink_undo" section (which would mean that they | |
211 | # have already been prelinked). | |
212 | set test "$test (missing /usr/sbin/prelink)" | |
213 | foreach bin [split $arg] { | |
214 | if [string match "-*" $bin] { | |
215 | # Skip prelink options. | |
216 | continue | |
217 | } | |
4fa7d390 | 218 | set readelf_program [gdb_find_readelf] |
1a219cc7 JK |
219 | set command "exec $readelf_program -WS $bin" |
220 | verbose -log "command is $command" | |
221 | set result [catch $command output] | |
222 | verbose -log "result is $result" | |
223 | verbose -log "output is $output" | |
224 | if {$result != 0 || [string match {* .gnu.prelink_undo *} $output]} { | |
225 | fail "$test ($bin is already prelinked)" | |
226 | return 0 | |
227 | } | |
228 | } | |
229 | pass $test | |
230 | return 1 | |
231 | } | |
5e3b36f8 JK |
232 | if {$result == 0 && $output == ""} { |
233 | verbose -log "$name has been now unprelinked" | |
234 | set command "exec /usr/sbin/prelink -uN $arg" | |
235 | verbose -log "command is $command" | |
236 | set result [catch $command output] | |
237 | verbose -log "result is $result" | |
238 | verbose -log "output is $output" | |
239 | } | |
240 | # Last line does miss the trailing \n. There can be multiple such messages | |
241 | # as ARG may list multiple files. | |
f61d5529 | 242 | if {$result == 1 && [regexp {^([^\r\n]*prelink[^\r\n]*: [^ ]* does not have .gnu.prelink_undo section\n?)*$} $output]} { |
5e3b36f8 JK |
243 | pass $test |
244 | return 1 | |
245 | } else { | |
246 | fail $test | |
247 | return 0 | |
248 | } | |
249 | } | |
250 | ||
251 | # Prelink ARG. Reported test name can be specified by NAME. Return non-zero | |
252 | # on success, zero on failure. | |
253 | ||
254 | proc prelink_yes {arg {name ""}} { | |
255 | if {$name == ""} { | |
256 | set name [file tail $arg] | |
257 | } | |
258 | ||
259 | # Try to unprelink it first so that, if it has been already prelinked | |
260 | # before, we get a different address now, making the new result unaffected | |
261 | # by any previous prelinking. | |
1a219cc7 JK |
262 | if ![prelink_no $arg "$name pre-unprelink"] { |
263 | return 0 | |
264 | } | |
5e3b36f8 JK |
265 | |
266 | set test "prelink $name" | |
267 | ||
268 | # `--no-exec-shield' is for i386, where prelink in the exec-shield mode is | |
269 | # forced to push all the libraries tight together, in order to fit into | |
270 | # the first two memory areas (either the ASCII Shield area or at least | |
271 | # below the executable). If the prelink was performed in exec-shield | |
272 | # mode, prelink could have no choice on how to randomize the single new | |
273 | # unprelinked library address without wasting space in the first one/two | |
274 | # memory areas. In such case prelink could place $ARG repeatedly at the | |
275 | # same place and we could have false prelink results on | |
276 | # gdb.base/prelink.exp and others. To prevent this from happening, we use | |
277 | # the --no-exec-shield switch. This may have some consequences in terms | |
278 | # of security, but we do not care in our case. | |
279 | ||
280 | set command "exec /usr/sbin/prelink -qNR --no-exec-shield $arg" | |
281 | ||
282 | verbose -log "command is $command" | |
283 | set result [catch $command output] | |
284 | verbose -log "result is $result" | |
285 | verbose -log "output is $output" | |
1a219cc7 JK |
286 | if {$result == 1 && [regexp {^(couldn't execute "/usr/sbin/prelink[^\r\n]*": no such file or directory\n?)*$} $output]} { |
287 | set test "$test (missing /usr/sbin/prelink)" | |
288 | ||
289 | # We could not find prelink. We could check whether $args is already | |
290 | # prelinked but we don't, because: | |
291 | # - It is unlikely that someone uninstalls prelink after having | |
292 | # prelinked the system ld.so; | |
293 | # - We still cannot change its prelinked address. | |
294 | # Therefore, we just skip the test. | |
295 | ||
296 | xfail $test | |
297 | return 0 | |
298 | } | |
70cc1c23 DE |
299 | if {$result == 1 && [regexp {DWARF [^\r\n]* unhandled} $output]} { |
300 | # Prelink didn't understand the version of dwarf present. | |
301 | unsupported "$test (dwarf version unhandled)" | |
302 | return 0 | |
303 | } | |
5e3b36f8 JK |
304 | if {$result == 0 && $output == ""} { |
305 | pass $test | |
306 | return 1 | |
307 | } elseif {$result == 1 \ | |
308 | && [string match -nocase "*: Not enough room to add .dynamic entry" $output]} { | |
309 | # Linker should have reserved some entries for prelink. | |
310 | xfail $test | |
311 | return 0 | |
312 | } else { | |
313 | fail $test | |
314 | return 0 | |
315 | } | |
316 | } |