summaryrefslogtreecommitdiff
path: root/gdb/testsuite/gdb.compile/compile.exp
blob: 15f7cf1916135304ea0f756c31e0191eda4d1659 (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
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
# Copyright 2014-2018 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/>.

standard_testfile .c compile-shlib.c compile-constvar.S compile-nodebug.c

get_compiler_info
set options {}
if [test_compiler_info gcc*] {
    lappend options additional_flags=-g3
}

if { ![istarget x86_64-*-* ] || ![is_lp64_target] } {
    verbose "Skipping x86_64 LOC_CONST test."
    set srcfile3 ""
}

set srcfilesoptions [list ${srcfile} ${options}]
if { $srcfile3 != "" } {
    lappend srcfilesoptions $srcfile3 ${options}
}
lappend srcfilesoptions $srcfile4 "nodebug"
if { [eval build_executable_from_specs ${testfile}.exp $testfile {$options} ${srcfilesoptions}] } {
    return -1
}

clean_restart ${testfile}

#
# Test command without an running inferior.
#
gdb_test "compile code int i=2;" \
    "The program must be running for the compile command to work.*" \
    "test compile code command without running inferior"

gdb_test "compile int i=2;" \
    "The program must be running for the compile command to work.*" \
    "test compile command without running inferior"

gdb_test "compile file -r ${srcdir}/${subdir}/${testfile}-mod.c" \
    "The program must be running for the compile command to work.*" \
    "test compile file command without running inferior"

if ![runto_main] {
    return -1
}

if {[skip_compile_feature_tests]} {
    untested "compile command not supported (could not find libcc1 shared library?)"
    return -1
}

#
# Test delimiter for code, and arguments.
#

gdb_test_no_output "compile -- f = 10" \
    "test abbreviations and code delimiter"

gdb_test "compile f = 10;" ".*= 10;: No such file.*" \
    "Test abbreviations and code collision"

gdb_test_no_output "compile -r -- void _gdb_expr(){int i = 5;}" \
    "test delimiter with -r"

gdb_test_no_output "compile -raw -- void _gdb_expr(){int i = 5;}" \
    "test delimiter with -raw"

gdb_test "compile -- -r  void _gdb_expr(){int i = 5;}" \
    ".* error: 'r' undeclared \\(first use in this function\\).*" \
    "test delimiter with -r after it"

gdb_test "p globalvar" " = 10" "expect 10"

gdb_test_no_output "compile code globalvar = 11" \
    "set variable without trailing semicolon"
gdb_test "p globalvar" " = 11" "check variable without trailing semicolon"

gdb_test_no_output "compile code globalvar = SOME_MACRO;" \
    "set variable from macro"
gdb_test "p globalvar" " = 23" "expect 23"

gdb_test_no_output "compile code globalvar = ARG_MACRO(0, 0);" \
    "set variable from function-like macro"
gdb_test "p globalvar" " = -1" "expect -1"

gdb_test_no_output "compile code globalvar = 42;" "set variable"
gdb_test "p globalvar" " = 42" "expect 42"

gdb_test_no_output "compile code globalvar *= 2;" "modify variable"
gdb_test "p globalvar" " = 84" "expect 84"

gdb_test_multiple "compile code" "compile code multiline 1" { -re "\r\n>$" {} }
gdb_test_multiple "globalvar = 10;" "compile code multiline 2" { -re "\r\n>$" {} }
gdb_test_multiple "globalvar *= 2;" "compile code multiline 3" { -re "\r\n>$" {} }
gdb_test_no_output "end" "compile code multiline 4"
gdb_test "p globalvar" " = 20" "expect 20"

gdb_test_no_output "compile file -r ${srcdir}/${subdir}/${testfile}-mod.c" \
    "use external source file"
gdb_test "p globalvar" " = 7" "expect 7"

gdb_test_no_output "compile code func_static (2);" "call static function"
gdb_test "p globalvar" " = 9" "expect 9"
gdb_test_no_output "compile code func_global (1);" "call global function"
gdb_test "p globalvar" " = 8" "expect 8"

gdb_test_no_output \
    "compile code globalvar = (sizeof (ulonger) == sizeof (long))" \
    "compute size of ulonger"
gdb_test "p globalvar" " = 1" "check size of ulonger"
gdb_test_no_output \
    "compile code globalvar = (sizeof (longer) == sizeof (long))" \
    "compute size of longer"
gdb_test "p globalvar" " = 1" "check size of longer"
gdb_test_no_output "compile code globalvar = MINUS_1"
gdb_test "p globalvar" " = -1" "check MINUS_1"

gdb_test_no_output "compile code globalvar = static_local"
gdb_test "p globalvar" " = 77000" "check static_local"

gdb_test_no_output "compile code static int staticvar = 5; intptr = &staticvar" \
    "do not keep jit in memory"
gdb_test "p *intptr" "Cannot access memory at address 0x\[0-9a-f\]+" "expect no 5"

gdb_test "compile code func_doesnotexist ();" "warning: Could not find symbol \"func_doesnotexist\" for .*"

gdb_test "compile code *(volatile int *) 0 = 0;" \
    "The program being debugged was signaled while in a function called from GDB\\.\r\nGDB remains in the frame where the signal was received\\.\r\n.*" \
    "compile code segfault first"
gdb_test "bt" \
    "\r\n#0  \[^\r\n\]* in _gdb_expr \[^\r\n\]*\r\n#1  <function called from gdb>\r\n.*"

set test "p/x \$pc"
set infcall_pc 0
gdb_test_multiple $test $test {
    -re " = (0x\[0-9a-f\]+)\r\n$gdb_prompt $" {
	set infcall_pc $expect_out(1,string)
	pass $test
    }
}

gdb_test "info sym $infcall_pc" "\r\n_gdb_expr .*" "info sym found"
gdb_test "return" "\r\n#0  main .*" "return" \
	 "Make _gdb_expr return now\\? \\(y or n\\) " "y"
gdb_test "info sym $infcall_pc" "\r\nNo symbol matches .*" "info sym not found"

gdb_test_no_output "set unwindonsignal on"
gdb_test "compile code *(volatile int *) 0 = 0;" \
    "The program being debugged was signaled while in a function called from GDB\\.\r\nGDB has restored the context to what it was before the call\\.\r\n.*" \
    "compile code segfault second"

gdb_breakpoint [gdb_get_line_number "break-here"]
gdb_continue_to_breakpoint "break-here" ".* break-here .*"

gdb_test "p localvar" " = 50" "expect localvar 50"

gdb_test_no_output "compile code localvar = 12;" "set localvar"
gdb_test "p localvar" " = 12" "expect 12"

gdb_test_no_output "compile code localvar *= 2;" "modify localvar"
gdb_test "p localvar" " = 24" "expect 24"

gdb_test_no_output "compile code localvar = shadowed" \
    "test shadowing"
gdb_test "p localvar" " = 52" "expect 52"

gdb_test_no_output "compile code localvar = externed"
gdb_test "p localvar" " = 7" "test extern in inner scope"

gdb_test_no_output "compile code vla\[2\] = 7"
gdb_test "p vla\[2\]" " = 7"
gdb_test_no_output \
    "compile code localvar = (sizeof (vla) == bound * sizeof (vla\[0\]))"
gdb_test "p localvar" " = 1"

#
# Test setting fields and also many different types.
#

set skip_struct_object 0
set test "compile code struct_object.selffield = &struct_object"
gdb_test_multiple $test $test {
    -re "^$test\r\n$gdb_prompt $" {
	pass "$test"
    }
    -re " error: Unexpected type id from GCC, check you use recent enough GCC\\.\r\n.*\r\n$gdb_prompt $" {
	xfail "$test (PR compile/18202)"

	# All following tests will break with the same error message.
	set skip_struct_object 1
    }
}

if {$skip_struct_object} {
    untested "all struct_object tests"
} else {
    gdb_test "print struct_object.selffield == &struct_object" " = 1"

    gdb_test_no_output "compile code struct_object.charfield = 1"
    gdb_test "print struct_object.charfield" " = 1 '\\\\001'"
    gdb_test_no_output "compile code struct_object.ucharfield = 1"
    gdb_test "print struct_object.ucharfield" " = 1 '\\\\001'"

    foreach {field value} {
	shortfield -5
	ushortfield 5
	intfield -7
	uintfield 7
	bitfield 2
	longfield -9
	ulongfield 9
	enumfield ONE
	floatfield 1
	doublefield 2
    } {
	gdb_test_no_output "compile code struct_object.$field = $value"
	gdb_test "print struct_object.$field" " = $value"
    }

    gdb_test_no_output "compile code struct_object.arrayfield\[2\] = 7"
    gdb_test "print struct_object.arrayfield" \
	" = \\{0, 0, 7, 0, 0\\}"

    gdb_test_no_output "compile code struct_object.complexfield = 7 + 5i"
    gdb_test "print struct_object.complexfield" " = 7 \\+ 5 \\* I"

    gdb_test_no_output "compile code struct_object.boolfield = 1"
    gdb_test "print struct_object.boolfield" " = true"

    gdb_test_no_output "compile code struct_object.vectorfield\[2\] = 7"
    gdb_test "print struct_object.vectorfield" \
	" = \\{0, 0, 7, 0\\}"

}

gdb_test_no_output "compile code union_object.typedeffield = 7"
gdb_test "print union_object.typedeffield" " = 7"
gdb_test "print union_object.intfield" " = 7"


# LOC_UNRESOLVED tests.

gdb_test "print unresolved" " = 20"
gdb_test "compile code globalvar = unresolved;"
gdb_test "print globalvar" " = 20" "print unresolved value"

# Test shadowing with global and static variables.

gdb_test_no_output "compile code globalshadow += 1;"
gdb_test "print globalshadow" " = 101"
gdb_test_no_output "compile code extern int globalshadow; globalshadow += 5;"
gdb_test "print 'compile.c'::globalshadow" " = 15"
gdb_test "print globalshadow" " = 101" "print globalshadow second time"
gdb_test_no_output "compile code staticshadow += 2;"
gdb_test "print staticshadow" " = 202"
# "extern int staticshadow;" cannot access static variable.

# Raw code cannot refer to locals.
# As it references global variable we need the #pragma.
# For #pragma we need multiline input.
gdb_test_multiple "compile code -r" "compile code -r multiline 1" { -re "\r\n>$" {} }
gdb_test_multiple "#pragma GCC user_expression" "compile code -r multiline 2" { -re "\r\n>$" {} }
gdb_test_multiple "void _gdb_expr(void) { globalshadow = 77000; }" "compile code -r multiline 3" { -re "\r\n>$" {} }
gdb_test_no_output "end" "compile code -r multiline 4"
gdb_test "print 'compile.c'::globalshadow" " = 77000" \
    "check globalshadow with -r"

# Test GOT vs. resolving jit function pointers.

gdb_test_no_output "compile -raw -- int func(){return 21;} void _gdb_expr(){ void abort (void); int (*funcp)()=func; if (funcp()!=21) abort(); }" \
    "pointer to jit function"

#
# Test the case where the registers structure would not normally have
# any fields.
#

gdb_breakpoint [gdb_get_line_number "no_args_or_locals breakpoint"]
gdb_continue_to_breakpoint "no_args_or_locals"

gdb_test_no_output "compile code globalvar = 77;" "set variable to 77"
gdb_test "p globalvar" " = 77" "expect 77"


# Test reference to minimal_symbol, not (full) symbol.

gdb_test "compile code globalvar = func_nodebug (75);" \
    "warning: function has unknown return type; assuming int" \
    "call func_nodebug"
gdb_test "p globalvar" " = -75" "expect -75"
gdb_test \
    "compile code int (*funcp) (int) = func_nodebug; globalvar = funcp (76);" \
    "warning: function has unknown return type; assuming int" \
    "call func_nodebug indirectly"
gdb_test "p globalvar" " = -76" "expect -76"


# Test compiled module memory protection.

gdb_test_no_output "set debug compile on"
gdb_test "compile code static const int readonly = 1; *(int *) &readonly = 2;" \
    "The program being debugged was signaled while in a function called from GDB\\.\r\nGDB has restored the context to what it was before the call\\.\r\n.*"
gdb_test_no_output "set debug compile off"


#
# Some simple coverage tests.
#

gdb_test "show debug compile" "Compile debugging is .*"
gdb_test "show compile-args" \
    "Compile command command-line arguments are .*"
gdb_test "compile code -z" "Unknown argument.*"

gdb_test "set lang rust" \
    "Warning: the current language does not match this frame."
gdb_test "compile code globalvar" "No compiler support for language rust\\."
gdb_test_no_output "set lang auto"

gdb_test_no_output "compile code union union_type newdecl_u"
gdb_test_no_output "compile code struct struct_type newdecl_s"
gdb_test_no_output "compile code inttypedef newdecl_i"

gdb_test "compile file" \
    "You must provide a filename for this command.*" \
    "Test compile file without a filename"
gdb_test "compile file -r" \
    "You must provide a filename with the raw option set.*" \
    "Test compile file and raw option without a filename"
gdb_test "compile file -z" \
    "Unknown argument.*" \
    "test compile file with unknown argument"


# LOC_CONST tests.

if { $srcfile3 != "" } {
    gdb_test "p constvar" " = 3"
    gdb_test "info addr constvar" {Symbol "constvar" is constant\.}

    gdb_test "compile code globalvar = constvar;"
    gdb_test "print globalvar" " = 3" "print constvar value"
} else {
    untested "print constvar value"
}

# Shared library tests.

if {[skip_shlib_tests]} {
    untested "skipping shlib tests"
    return;
}

set libbin [standard_output_file ${testfile}-shlib.so]
set binfile [standard_output_file ${testfile}-shlib]

if { [gdb_compile_shlib ${srcdir}/${subdir}/${srcfile2} $libbin {debug}] != ""
     || [gdb_compile ${srcdir}/${subdir}/${srcfile} $binfile executable \
	     [list debug shlib=$libbin]] == -1 } {
    return -1
}

clean_restart $binfile
gdb_load_shlib $libbin

if ![runto_main] {
    return -1
}

gdb_test_no_output "compile code shlib_func ();" "call shared library function"
gdb_test "p globalvar" " = 1" "expect 1"

gdb_test_no_output "compile code shlibvar += 5;" "modify shared library variable"
gdb_test "p shlibvar" " = 15" "expect 15"