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