aboutsummaryrefslogtreecommitdiff
blob: cc625e01edae42df7e9f065e5e08da692ba4bdfa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
# Copyright 2002, 2003, 2005, 2007, 2008, 2009, 2010
# Free Software Foundation, Inc.

# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

# code_elim.exp -- tests that GDB can handle executables where some data/code
#                  has been eliminated by the linker.

if $tracelevel then {
    strace $tracelevel
}

set testfile1 code_elim1
set testfile2 code_elim2
set srcfile1 ${testfile1}.c
set srcfile2 ${testfile2}.c
set binfile1 ${objdir}/${subdir}/${testfile1}
set binfile2 ${objdir}/${subdir}/${testfile2}
set opts [list debug]
lappend opts "additional_flags=-ffunction-sections"
lappend opts "additional_flags=-fdata-sections"
lappend opts "additional_flags=-Wl,-gc-sections"
lappend opts "additional_flags=-Wl,-e,main"

remote_exec build "rm -f ${binfile1}"
remote_exec build "rm -f ${binfile2}"

if { [gdb_compile "${srcdir}/${subdir}/${srcfile1}" "${binfile1}" executable $opts] != "" } {
     untested code_elim.exp
     return -1
}

if { [gdb_compile "${srcdir}/${subdir}/${srcfile2}" "${binfile2}" executable $opts] != "" } {
     untested code_elim.exp
     return -1
}

proc get_var_address { var } {
    global gdb_prompt hex

    # Match output like:
    # $1 = (int *) 0x0
    # $5 = (int (*)()) 0
    # $6 = (int (*)()) 0x24 <function_bar>

    gdb_test_multiple "print &${var}" "get address of ${var}" {
	-re "\\\$\[0-9\]+ = \\(.*\\) (0|$hex)( <${var}>)?\[\r\n\]+${gdb_prompt} $" {
	    pass "get address of ${var}"
	    if { $expect_out(1,string) == "0" } {
		return "0x0"
	    } else {
		return $expect_out(1,string)
	    }
	}
    }
    return ""
}

proc not_null_var_address { var } {

    # Same as get_var_address, expect that it reports a failure if a null
    # address is returned by gdb.

    set address [get_var_address $var]
    regexp "0x\[0-9a-fA-F\]+" $address address
    if { "$address" == "0x0" } {
	fail "$var has null address"
    }
}

proc test_eliminated_var { var } {
    global gdb_prompt hex

    # Match output 'No symbol "${var}" in current context'

    gdb_test_multiple "print &${var}" "test eliminated var ${var}" {
	-re "No symbol \"${var}\" in current context\\.\[\r\n\]+${gdb_prompt} $" {
	    pass "test eliminated var ${var}"
	}
	-re "\\\$\[0-9\]+ = \\(.*\\) (0|$hex)( <${var}>)?\[\r\n\]+${gdb_prompt} $" {
	    fail "test eliminated var ${var}"
	}
    }
}

# Check that the code and data eliminated in binfile1 are not included
# into partial symtab... and that non-eliminated symbols are still there.

gdb_exit
gdb_start

gdb_test "add-symbol-file ${binfile1} 0x100000" \
	"Reading symbols from .*${testfile1}\\.\\.\\.done\\.(|\r\nUsing host libthread_db library .*libthread_db.so.*\\.)" \
	"add-symbol-file ${testfile1} 0x100000" \
	"add symbol table from file \".*${testfile1}\" at\[ \t\r\n\]+\.text_addr = 0x100000\[\r\n\]+\\(y or n\\) " \
	"y"

test_eliminated_var my_global_symbol
test_eliminated_var my_static_symbol
test_eliminated_var my_global_func
not_null_var_address main

# Same thing for symtabs

gdb_exit
global GDBFLAGS
set saved_gdbflags $GDBFLAGS
set GDBFLAGS "$GDBFLAGS --readnow $binfile1"
gdb_start
set GDBFLAGS $saved_gdbflags

test_eliminated_var my_global_symbol
test_eliminated_var my_static_symbol
test_eliminated_var my_global_func
not_null_var_address main

# binfile2 contains the symbols that have been eliminated in binfile1. Check
# the eliminated symbols does not hide these valid ones.

gdb_exit
gdb_start

gdb_test "add-symbol-file ${binfile1} 0x100000" \
	"Reading symbols from .*${testfile1}\\.\\.\\.done\\." \
	"add-symbol-file ${testfile1} 0x100000" \
	"add symbol table from file \".*${testfile1}\" at\[ \t\r\n\]+\.text_addr = 0x100000\[\r\n\]+\\(y or n\\) " \
	"y"

gdb_test "add-symbol-file ${binfile2} 0x200000" \
	"Reading symbols from .*${testfile2}\\.\\.\\.done\\." \
	"add-symbol-file ${testfile2} 0x200000" \
	"add symbol table from file \".*${testfile2}\" at\[ \t\r\n\]+\.text_addr = 0x200000\[\r\n\]+\\(y or n\\) " \
	"y"

not_null_var_address my_global_symbol
not_null_var_address my_static_symbol
not_null_var_address my_global_func
not_null_var_address main

# Same thing, but loading binfile2 before binfile1.

gdb_exit
gdb_start

gdb_test "add-symbol-file ${binfile2} 0x200000" \
	"Reading symbols from .*${testfile2}\\.\\.\\.done\\." \
	"add-symbol-file ${testfile2} 0x200000" \
	"add symbol table from file \".*${testfile2}\" at\[ \t\r\n\]+\.text_addr = 0x200000\[\r\n\]+\\(y or n\\) " \
	"y"

gdb_test "add-symbol-file ${binfile1} 0x100000" \
	"Reading symbols from .*${testfile1}\\.\\.\\.done\\." \
	"add-symbol-file ${testfile1} 0x100000" \
	"add symbol table from file \".*${testfile1}\" at\[ \t\r\n\]+\.text_addr = 0x100000\[\r\n\]+\\(y or n\\) " \
	"y"

not_null_var_address my_global_symbol
not_null_var_address my_static_symbol
not_null_var_address my_global_func
not_null_var_address main