OLD | NEW |
1 # Copyright (C) 2010-2012 Free Software Foundation, Inc. | 1 # Copyright (C) 2010-2013 Free Software Foundation, Inc. |
2 | 2 |
3 # This program is free software; you can redistribute it and/or modify | 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 | 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 | 5 # the Free Software Foundation; either version 3 of the License, or |
6 # (at your option) any later version. | 6 # (at your option) any later version. |
7 # | 7 # |
8 # This program is distributed in the hope that it will be useful, | 8 # This program is distributed in the hope that it will be useful, |
9 # but WITHOUT ANY WARRANTY; without even the implied warranty of | 9 # but WITHOUT ANY WARRANTY; without even the implied warranty of |
10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 10 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
11 # GNU General Public License for more details. | 11 # GNU General Public License for more details. |
12 # | 12 # |
13 # You should have received a copy of the GNU General Public License | 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/>. | 14 # along with this program. If not, see <http://www.gnu.org/licenses/>. |
15 | 15 |
16 # Return nul-terminated string read from section SECTION of EXEC. Return "" | 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 | 17 # if no such section or nul-terminated string was found. Function is useful |
18 # for sections ".interp" or ".gnu_debuglink". | 18 # for sections ".interp" or ".gnu_debuglink". |
19 | 19 |
20 proc section_get {exec section} { | 20 proc section_get {exec section} { |
21 global objdir | |
22 global subdir | 21 global subdir |
23 set tmp "${objdir}/${subdir}/section_get.tmp" | 22 set tmp [standard_output_file section_get.tmp] |
24 set objcopy_program [transform objcopy] | 23 set objcopy_program [gdb_find_objcopy] |
25 | 24 |
26 set command "exec $objcopy_program -O binary --set-section-flags $section=A
--change-section-address $section=0 -j $section $exec $tmp" | 25 set command "exec $objcopy_program -O binary --set-section-flags $section=A
--change-section-address $section=0 -j $section $exec $tmp" |
27 verbose -log "command is $command" | 26 verbose -log "command is $command" |
28 set result [catch $command output] | 27 set result [catch $command output] |
29 verbose -log "result is $result" | 28 verbose -log "result is $result" |
30 verbose -log "output is $output" | 29 verbose -log "output is $output" |
31 if {$result == 1} { | 30 if {$result == 1} { |
32 return "" | 31 return "" |
33 } | 32 } |
34 set fi [open $tmp] | 33 set fi [open $tmp] |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
88 return 0 | 87 return 0 |
89 } else { | 88 } else { |
90 pass $test | 89 pass $test |
91 return 1 | 90 return 1 |
92 } | 91 } |
93 } | 92 } |
94 | 93 |
95 # Wrap function build_executable so that the resulting executable is fully | 94 # Wrap function build_executable so that the resulting executable is fully |
96 # self-sufficient (without dependencies on system libraries). Parameter | 95 # self-sufficient (without dependencies on system libraries). Parameter |
97 # INTERP may be used to specify a loader (ld.so) to be used that is | 96 # INTERP may be used to specify a loader (ld.so) to be used that is |
98 # different from the default system one. Libraries on which the executable | 97 # different from the default system one. INTERP can be set to "no" if no ld.so |
99 # depends are copied into directory DIR. Default DIR value to | 98 # copy should be made. Libraries on which the executable depends are copied |
| 99 # into directory DIR. Default DIR value to |
100 # `${objdir}/${subdir}/${EXECUTABLE}.d'. | 100 # `${objdir}/${subdir}/${EXECUTABLE}.d'. |
101 # | 101 # |
102 # In case of success, return a string containing the arguments to be used | 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 | 103 # in order to perform a prelink of the executable obtained. Return the |
104 # empty string in case of failure. | 104 # empty string in case of failure. |
105 # | 105 # |
106 # This can be useful when trying to prelink an executable which might | 106 # This can be useful when trying to prelink an executable which might |
107 # depend on system libraries. To properly prelink an executable, all | 107 # depend on system libraries. To properly prelink an executable, all |
108 # of its dynamically linked libraries must be prelinked as well. If | 108 # of its dynamically linked libraries must be prelinked as well. If |
109 # the executable depends on some system libraries, we may not have | 109 # the executable depends on some system libraries, we may not have |
110 # sufficient write priviledges on these files to perform the prelink. | 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 | 111 # This is why we make a copy of these shared libraries, and link the |
112 # executable against these copies instead. | 112 # executable against these copies instead. |
113 # | 113 # |
114 # Function recognizes only libraries listed by `ldd' after | 114 # Function recognizes only libraries listed by `ldd' after |
115 # its ` => ' separator. That means $INTERP and any libraries not being linked | 115 # its ` => ' separator. That means $INTERP and any libraries not being linked |
116 # with -Wl,-soname,NAME.so are not copied. | 116 # with -Wl,-soname,NAME.so are not copied. |
117 | 117 |
118 proc build_executable_own_libs {testname executable sources options {interp ""}
{dir ""}} { | 118 proc build_executable_own_libs {testname executable sources options {interp ""}
{dir ""}} { |
119 global objdir subdir | 119 global subdir |
120 | 120 |
121 if {[build_executable $testname $executable $sources $options] == -1} { | 121 if {[build_executable $testname $executable $sources $options] == -1} { |
122 return "" | 122 return "" |
123 } | 123 } |
124 set binfile ${objdir}/${subdir}/${executable} | 124 set binfile [standard_output_file ${executable}] |
125 | 125 |
126 set command "ldd $binfile" | 126 set ldd [gdb_find_ldd] |
| 127 set command "$ldd $binfile" |
127 set test "ldd $executable" | 128 set test "ldd $executable" |
128 set result [catch "exec $command" output] | 129 set result [catch "exec $command" output] |
129 verbose -log "result of $command is $result" | 130 verbose -log "result of $command is $result" |
130 verbose -log "output of $command is $output" | 131 verbose -log "output of $command is $output" |
131 if {$result != 0 || $output == ""} { | 132 if {$result != 0 || $output == ""} { |
132 fail $test | 133 fail $test |
133 } else { | 134 } else { |
134 pass $test | 135 pass $test |
135 } | 136 } |
136 | 137 |
137 # gdb testsuite will put there also needless -lm. | 138 # gdb testsuite will put there also needless -lm. |
138 set test "$test output contains libs" | 139 set test "$test output contains libs" |
139 set libs [regexp -all -inline -line {^.* => (/[^ ]+).*$} $output] | 140 set libs [regexp -all -inline -line {^.* => (/[^ ]+).*$} $output] |
140 if {[llength $libs] == 0} { | 141 if {[llength $libs] == 0} { |
141 fail $test | 142 fail $test |
142 } else { | 143 } else { |
143 pass $test | 144 pass $test |
144 } | 145 } |
145 | 146 |
146 if {$dir == ""} { | 147 if {$dir == ""} { |
147 set dir ${binfile}.d | 148 set dir ${binfile}.d |
148 } | 149 } |
149 file delete -force -- $dir | 150 file delete -force -- $dir |
150 file mkdir $dir | 151 file mkdir $dir |
151 | 152 |
152 if {$interp == ""} { | 153 if {$interp == ""} { |
153 set interp_system [section_get $binfile .interp] | 154 set interp_system [section_get $binfile .interp] |
154 » set interp ${dir}/[file tail $interp_system] | 155 » if {$interp_system == ""} { |
155 » file_copy $interp_system $interp | 156 » fail "$test could not find .interp" |
| 157 » } else { |
| 158 » set interp ${dir}/[file tail $interp_system] |
| 159 » file_copy $interp_system $interp |
| 160 » } |
| 161 } |
| 162 if {$interp == "no"} { |
| 163 » set interp "" |
156 } | 164 } |
157 | 165 |
158 set dests {} | 166 set dests {} |
159 foreach {trash abspath} $libs { | 167 foreach {trash abspath} $libs { |
160 set dest "$dir/[file tail $abspath]" | 168 set dest "$dir/[file tail $abspath]" |
161 file_copy $abspath $dest | 169 file_copy $abspath $dest |
162 lappend dests $dest | 170 lappend dests $dest |
163 } | 171 } |
164 | 172 |
165 # Do not lappend it so that "-rpath $dir" overrides any possible "-rpath"s | 173 # Do not lappend it so that "-rpath $dir" overrides any possible "-rpath"s |
166 # specified by the caller to be able to link it for ldd" above. | 174 # specified by the caller to be able to link it for ldd" above. |
167 set options [linsert $options 0 "ldflags=-Wl,--dynamic-linker,$interp,-rpath
,$dir"] | 175 set options [linsert $options 0 "ldflags=-Wl,-rpath,$dir"] |
| 176 if {$interp != ""} { |
| 177 » set options [linsert $options 0 "ldflags=-Wl,--dynamic-linker,$interp"] |
| 178 } |
168 | 179 |
169 if {[build_executable $testname $executable $sources $options] == -1} { | 180 if {[build_executable $testname $executable $sources $options] == -1} { |
170 return "" | 181 return "" |
171 } | 182 } |
172 | 183 |
173 set prelink_args "--dynamic-linker=$interp --ld-library-path=$dir $binfile $
interp [concat $dests]" | 184 set prelink_args "--ld-library-path=$dir $binfile [concat $dests]" |
| 185 if {$interp != ""} { |
| 186 » set prelink_args "--dynamic-linker=$interp $prelink_args $interp" |
| 187 } |
174 return $prelink_args | 188 return $prelink_args |
175 } | 189 } |
176 | 190 |
177 # Unprelink ARG. Reported test name can be specified by NAME. Return non-zero | 191 # Unprelink ARG. Reported test name can be specified by NAME. Return non-zero |
178 # on success, zero on failure. | 192 # on success, zero on failure. |
179 | 193 |
180 proc prelink_no {arg {name {}}} { | 194 proc prelink_no {arg {name {}}} { |
181 if {$name == ""} { | 195 if {$name == ""} { |
182 set name [file tail $arg] | 196 set name [file tail $arg] |
183 } | 197 } |
184 set test "unprelink $name" | 198 set test "unprelink $name" |
185 set command "exec /usr/sbin/prelink -uN $arg" | 199 set command "exec /usr/sbin/prelink -uN $arg" |
186 verbose -log "command is $command" | 200 verbose -log "command is $command" |
187 set result [catch $command output] | 201 set result [catch $command output] |
188 verbose -log "result is $result" | 202 verbose -log "result is $result" |
189 verbose -log "output is $output" | 203 verbose -log "output is $output" |
190 if {$result == 1 && [regexp {^(couldn't execute "/usr/sbin/prelink[^\r\n]*":
no such file or directory\n?)*$} $output]} { | 204 if {$result == 1 && [regexp {^(couldn't execute "/usr/sbin/prelink[^\r\n]*":
no such file or directory\n?)*$} $output]} { |
191 # Without prelink, at least verify that all the binaries do not | 205 # Without prelink, at least verify that all the binaries do not |
192 # contain the ".gnu.prelink_undo" section (which would mean that they | 206 # contain the ".gnu.prelink_undo" section (which would mean that they |
193 # have already been prelinked). | 207 # have already been prelinked). |
194 set test "$test (missing /usr/sbin/prelink)" | 208 set test "$test (missing /usr/sbin/prelink)" |
195 foreach bin [split $arg] { | 209 foreach bin [split $arg] { |
196 if [string match "-*" $bin] { | 210 if [string match "-*" $bin] { |
197 # Skip prelink options. | 211 # Skip prelink options. |
198 continue | 212 continue |
199 } | 213 } |
200 » set readelf_program [transform readelf] | 214 » set readelf_program [gdb_find_readelf] |
201 set command "exec $readelf_program -WS $bin" | 215 set command "exec $readelf_program -WS $bin" |
202 verbose -log "command is $command" | 216 verbose -log "command is $command" |
203 set result [catch $command output] | 217 set result [catch $command output] |
204 verbose -log "result is $result" | 218 verbose -log "result is $result" |
205 verbose -log "output is $output" | 219 verbose -log "output is $output" |
206 if {$result != 0 || [string match {* .gnu.prelink_undo *} $output]}
{ | 220 if {$result != 0 || [string match {* .gnu.prelink_undo *} $output]}
{ |
207 fail "$test ($bin is already prelinked)" | 221 fail "$test ($bin is already prelinked)" |
208 return 0 | 222 return 0 |
209 } | 223 } |
210 } | 224 } |
211 pass $test | 225 pass $test |
212 return 1 | 226 return 1 |
213 } | 227 } |
214 if {$result == 0 && $output == ""} { | 228 if {$result == 0 && $output == ""} { |
215 verbose -log "$name has been now unprelinked" | 229 verbose -log "$name has been now unprelinked" |
216 set command "exec /usr/sbin/prelink -uN $arg" | 230 set command "exec /usr/sbin/prelink -uN $arg" |
217 verbose -log "command is $command" | 231 verbose -log "command is $command" |
218 set result [catch $command output] | 232 set result [catch $command output] |
219 verbose -log "result is $result" | 233 verbose -log "result is $result" |
220 verbose -log "output is $output" | 234 verbose -log "output is $output" |
221 } | 235 } |
222 # Last line does miss the trailing \n. There can be multiple such messages | 236 # Last line does miss the trailing \n. There can be multiple such messages |
223 # as ARG may list multiple files. | 237 # as ARG may list multiple files. |
224 if {$result == 1 && [regexp {^(/usr/sbin/prelink[^\r\n]*: [^ ]* does not hav
e .gnu.prelink_undo section\n?)*$} $output]} { | 238 if {$result == 1 && [regexp {^([^\r\n]*prelink[^\r\n]*: [^ ]* does not have
.gnu.prelink_undo section\n?)*$} $output]} { |
225 pass $test | 239 pass $test |
226 return 1 | 240 return 1 |
227 } else { | 241 } else { |
228 fail $test | 242 fail $test |
229 return 0 | 243 return 0 |
230 } | 244 } |
231 } | 245 } |
232 | 246 |
233 # Prelink ARG. Reported test name can be specified by NAME. Return non-zero | 247 # Prelink ARG. Reported test name can be specified by NAME. Return non-zero |
234 # on success, zero on failure. | 248 # on success, zero on failure. |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
271 # We could not find prelink. We could check whether $args is already | 285 # We could not find prelink. We could check whether $args is already |
272 # prelinked but we don't, because: | 286 # prelinked but we don't, because: |
273 # - It is unlikely that someone uninstalls prelink after having | 287 # - It is unlikely that someone uninstalls prelink after having |
274 # prelinked the system ld.so; | 288 # prelinked the system ld.so; |
275 # - We still cannot change its prelinked address. | 289 # - We still cannot change its prelinked address. |
276 # Therefore, we just skip the test. | 290 # Therefore, we just skip the test. |
277 | 291 |
278 xfail $test | 292 xfail $test |
279 return 0 | 293 return 0 |
280 } | 294 } |
| 295 if {$result == 1 && [regexp {DWARF [^\r\n]* unhandled} $output]} { |
| 296 # Prelink didn't understand the version of dwarf present. |
| 297 unsupported "$test (dwarf version unhandled)" |
| 298 return 0 |
| 299 } |
281 if {$result == 0 && $output == ""} { | 300 if {$result == 0 && $output == ""} { |
282 pass $test | 301 pass $test |
283 return 1 | 302 return 1 |
284 } elseif {$result == 1 \ | 303 } elseif {$result == 1 \ |
285 && [string match -nocase "*: Not enough room to add .dynamic entry
" $output]} { | 304 && [string match -nocase "*: Not enough room to add .dynamic entry
" $output]} { |
286 # Linker should have reserved some entries for prelink. | 305 # Linker should have reserved some entries for prelink. |
287 xfail $test | 306 xfail $test |
288 return 0 | 307 return 0 |
289 } else { | 308 } else { |
290 fail $test | 309 fail $test |
291 return 0 | 310 return 0 |
292 } | 311 } |
293 } | 312 } |
OLD | NEW |