1# Copyright 2012-2013 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, see <http://www.gnu.org/licenses/>. 15 16standard_testfile 17 18if [build_executable ${testfile}.exp $testfile] { 19 return -1 20} 21 22# A wrapper for 'remote_exec host' that passes or fails a test. 23# Returns 0 if all went well, nonzero on failure. 24# TEST is the name of the test, other arguments are as for 25# remote_exec. 26proc run {test program args} { 27 verbose "cmdline is remote_exec host $program $args" 28 # remote_exec doesn't work properly if the output is set but the 29 # input is the empty string -- so replace an empty input with 30 # /dev/null. 31 if {[llength $args] > 1 && [lindex $args 1] == ""} { 32 set args [lreplace $args 1 1 "/dev/null"] 33 } 34 set result [eval remote_exec host [list $program] $args] 35 verbose "result is $result" 36 set status [lindex $result 0] 37 set output [lindex $result 1] 38 if {$status == 0} { 39 pass $test 40 return 0 41 } else { 42 fail $test 43 return -1 44 } 45} 46 47set pipeline_counter 0 48 49# Run a pipeline of processes through 'run'. 50# TEST is the base name of the test, it is modified and passed to 'run'. 51# Each subsequent argument is a list of the form {PROGRAM [ARG]...}. 52# It is passed to 'run'. However, before being passed, if input and output 53# files are not specified in the list, then this proc provides them. 54# Each program in the pipeline takes its input from the previous 55# program's output. 56proc pipeline {test args} { 57 global pipeline_counter 58 59 set input_file {} 60 foreach arglist $args { 61 verbose "raw args are $arglist" 62 63 set program [lindex $arglist 0] 64 set arguments [lindex $arglist 1] 65 set input [lindex $arglist 2] 66 set output [lindex $arglist 3] 67 68 if {$input == ""} { 69 set input $input_file 70 } 71 if {$output == ""} { 72 set output [standard_output_file pipe.[pid].$pipeline_counter] 73 incr pipeline_counter 74 } 75 verbose "cooked args are [list $program $arguments $input $output]" 76 77 if {[run "$test - invoke $program" $program $arguments \ 78 $input $output]} { 79 return -1 80 } 81 82 set input_file $output 83 } 84 return 0 85} 86 87# Extract the dynamic symbols from the main binary, there is no need 88# to also have these in the normal symbol table. 89remote_file host delete ${binfile}.dynsyms 90if {[pipeline "nm -D" \ 91 [list [transform nm] "-D ${binfile} --format=posix --defined-only"] \ 92 [list awk "\\{print\\ \\\$1\\}"] \ 93 [list sort "" "" "${binfile}.dynsyms"]]} { 94 return -1 95} 96 97# Extract all the text (i.e. function) symbols from the debuginfo. 98# (Note that we actually also accept "D" symbols, for the benefit 99# of platforms like PowerPC64 that use function descriptors.) 100remote_file host delete ${binfile}.funcsyms 101if {[pipeline "nm" \ 102 [list [transform nm] "${binfile} --format=posix --defined-only"] \ 103 [list awk "\\{if(\\\$2==\"T\"||\\\$2==\"t\"||\\\$2==\"D\")print\\ \\\$1\\}"] \ 104 [list sort "" "" "${binfile}.funcsyms"]]} { 105 return -1 106} 107 108# Keep all the function symbols not already in the dynamic symbol 109# table. 110remote_file host delete ${binfile}.keep_symbols 111if {[run "comm" "comm" "-13 ${binfile}.dynsyms ${binfile}.funcsyms" "" \ 112 "${binfile}.keep_symbols"]} { 113 return -1 114} 115 116# Copy the full debuginfo, keeping only a minimal set of symbols and 117# removing some unnecessary sections. 118remote_file host delete ${binfile}.mini_debuginfo 119if {[run "objcopy 1" [transform objcopy] "-S --remove-section .gdb_index --remove-section .comment --keep-symbols=${binfile}.keep_symbols ${binfile} ${binfile}.mini_debuginfo"]} { 120 return -1 121} 122 123# GDB specific - we do not have split executable in advance. 124remote_file host delete ${binfile}.strip 125if {[run "strip" [transform strip] \ 126 "--strip-all -o ${binfile}.strip ${binfile}"]} { 127 return -1 128} 129 130# Separate full debug info into ${binfile}.debug. 131remote_file host delete ${binfile}.debug 132if {[run "copydebug" [transform objcopy] \ 133 "--only-keep-debug ${binfile} ${binfile}.debug"]} { 134 return -1 135} 136 137# Add the .gnu_debuglink section to the .gnu_debugdata file. 138# .gnu_debuglink is normally not present in the .gnu_debugdata section but in 139# some files there may be PT_NOTE with NT_GNU_BUILD_ID and GDB could look up 140# the .debug file from it. 141if {[run "addlink" [transform objcopy] \ 142 "--add-gnu-debuglink=${binfile}.debug ${binfile}.mini_debuginfo ${binfile}.mini_debuginfo-debuglink"]} { 143 return -1 144} 145 146# Inject the compressed data into the .gnu_debugdata section of the 147# original binary. 148remote_file host delete ${binfile}.mini_debuginfo-debuglink.xz 149if {[run "xz" "xz" "-k ${binfile}.mini_debuginfo-debuglink"]} { 150 return -1 151} 152remote_file host delete ${binfile}.test 153if {[run "objcopy 2" [transform objcopy] "--add-section .gnu_debugdata=${binfile}.mini_debuginfo-debuglink.xz ${binfile}.strip ${binfile}.test"]} { 154 return -1 155} 156 157clean_restart "$testfile.strip" 158 159gdb_test "p debugdata_function" \ 160 {No symbol table is loaded\. Use the "file" command\.} \ 161 "no symtab" 162 163clean_restart "$testfile.test" 164 165if {$gdb_file_cmd_debug_info == "lzma"} { 166 unsupported "LZMA support not available in this gdb" 167} else { 168 gdb_test "p debugdata_function" \ 169 { = {<text variable, no debug info>} 0x[0-9a-f]+ <debugdata_function>} \ 170 "have symtab" 171} 172 173# Be sure to test the 'close' method on the MiniDebugInfo BFD. 174if {[gdb_unload]} { 175 fail "unload MiniDebugInfo" 176} else { 177 pass "unload MiniDebugInfo" 178} 179 180gdb_exit 181