GDB copyright headers update after running GDB's copyright.py script.
[deliverable/binutils-gdb.git] / gdb / testsuite / gdb.arch / insn-reloc.c
CommitLineData
4f51c22a
PL
1/* This testcase is part of GDB, the GNU debugger.
2
618f726f 3 Copyright 2015-2016 Free Software Foundation, Inc.
4f51c22a
PL
4
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>. */
17
18#include <stddef.h>
19#include <stdint.h>
20
21typedef void (*testcase_ftype)(void);
22
23/* Each function checks the correctness of the instruction being
24 relocated due to a fast tracepoint. Call function pass if it is
25 correct, otherwise call function fail. GDB sets a breakpoints on
26 pass and fail in order to check the correctness. */
27
28static void
29pass (void)
30{
31}
32
33static void
34fail (void)
35{
36}
37
38#if (defined __x86_64__ || defined __i386__)
39
40#ifdef SYMBOL_PREFIX
41#define SYMBOL(str) SYMBOL_PREFIX #str
42#else
43#define SYMBOL(str) #str
44#endif
45
46/* Make sure we can relocate a CALL instruction. CALL instructions are
47 5 bytes long so we can always set a fast tracepoints on them.
48
49 JMP set_point0
50 f:
51 MOV $1, %[ok]
52 JMP end
53 set_point0:
54 CALL f ; tracepoint here.
55 end:
56
57 */
58
59static void
60can_relocate_call (void)
61{
62 int ok = 0;
63
64 asm (" .global " SYMBOL (set_point0) "\n"
65 " jmp " SYMBOL (set_point0) "\n"
66 "0:\n"
67 " mov $1, %[ok]\n"
68 " jmp 1f\n"
69 SYMBOL (set_point0) ":\n"
70 " call 0b\n"
71 "1:\n"
72 : [ok] "=r" (ok));
73
74 if (ok == 1)
75 pass ();
76 else
77 fail ();
78}
79
80/* Make sure we can relocate a JMP instruction. We need the JMP
81 instruction to be 5 bytes long in order to set a fast tracepoint on
82 it. To do this, we emit the opcode directly.
83
84 JMP next ; tracepoint here.
85 next:
86 MOV $1, %[ok]
87
88 */
89
90static void
91can_relocate_jump (void)
92{
93 int ok = 0;
94
95 asm (" .global " SYMBOL (set_point1) "\n"
96 SYMBOL (set_point1) ":\n"
97 ".byte 0xe9\n" /* jmp */
98 ".byte 0x00\n"
99 ".byte 0x00\n"
100 ".byte 0x00\n"
101 ".byte 0x00\n"
102 " mov $1, %[ok]\n"
103 : [ok] "=r" (ok));
104
105 if (ok == 1)
106 pass ();
107 else
108 fail ();
109}
110#elif (defined __aarch64__)
111
112/* Make sure we can relocate a B instruction.
113
114 B set_point0
115 set_ok:
116 MOV %[ok], #1
117 B end
118 set_point0:
119 B set_ok ; tracepoint here.
120 MOV %[ok], #0
121 end
122
123 */
124
125static void
126can_relocate_b (void)
127{
128 int ok = 0;
129
130 asm (" b set_point0\n"
131 "0:\n"
132 " mov %[ok], #1\n"
133 " b 1f\n"
134 "set_point0:\n"
135 " b 0b\n"
136 " mov %[ok], #0\n"
137 "1:\n"
138 : [ok] "=r" (ok));
139
140 if (ok == 1)
141 pass ();
142 else
143 fail ();
144}
145
146/* Make sure we can relocate a B.cond instruction.
147
148 MOV x0, #8
149 TST x0, #8 ; Clear the Z flag.
150 B set_point1
151 set_ok:
152 MOV %[ok], #1
153 B end
154 set_point1:
155 B.NE set_ok ; tracepoint here.
156 MOV %[ok], #0
157 end
158
159 */
160
161static void
8240f442 162can_relocate_bcond_true (void)
4f51c22a
PL
163{
164 int ok = 0;
165
166 asm (" mov x0, #8\n"
167 " tst x0, #8\n"
168 " b set_point1\n"
169 "0:\n"
170 " mov %[ok], #1\n"
171 " b 1f\n"
172 "set_point1:\n"
173 " b.ne 0b\n"
174 " mov %[ok], #0\n"
175 "1:\n"
176 : [ok] "=r" (ok)
177 :
178 : "0", "cc");
179
180 if (ok == 1)
181 pass ();
182 else
183 fail ();
184}
185
186/* Make sure we can relocate a CBZ instruction.
187
188 MOV x0, #0
189 B set_point2
190 set_ok:
191 MOV %[ok], #1
192 B end
193 set_point2:
194 CBZ x0, set_ok ; tracepoint here.
195 MOV %[ok], #0
196 end
197
198 */
199
200static void
201can_relocate_cbz (void)
202{
203 int ok = 0;
204
205 asm (" mov x0, #0\n"
206 " b set_point2\n"
207 "0:\n"
208 " mov %[ok], #1\n"
209 " b 1f\n"
210 "set_point2:\n"
211 " cbz x0, 0b\n"
212 " mov %[ok], #0\n"
213 "1:\n"
214 : [ok] "=r" (ok)
215 :
216 : "0");
217
218 if (ok == 1)
219 pass ();
220 else
221 fail ();
222}
223
224/* Make sure we can relocate a CBNZ instruction.
225
226 MOV x0, #8
227 B set_point3
228 set_ok:
229 MOV %[ok], #1
230 B end
231 set_point3:
232 CBNZ x0, set_ok ; tracepoint here.
233 MOV %[ok], #0
234 end
235
236 */
237
238static void
239can_relocate_cbnz (void)
240{
241 int ok = 0;
242
243 asm (" mov x0, #8\n"
244 " b set_point3\n"
245 "0:\n"
246 " mov %[ok], #1\n"
247 " b 1f\n"
248 "set_point3:\n"
249 " cbnz x0, 0b\n"
250 " mov %[ok], #0\n"
251 "1:\n"
252 : [ok] "=r" (ok)
253 :
254 : "0");
255
256 if (ok == 1)
257 pass ();
258 else
259 fail ();
260}
261
262/* Make sure we can relocate a TBZ instruction.
263
264 MOV x0, #8
265 MVN x0, x0 ; Clear bit 3.
266 B set_point4
267 set_ok:
268 MOV %[ok], #1
269 B end
270 set_point4:
271 TBZ x0, #3, set_ok ; tracepoint here.
272 MOV %[ok], #0
273 end
274
275 */
276
277static void
278can_relocate_tbz (void)
279{
280 int ok = 0;
281
282 asm (" mov x0, #8\n"
283 " mvn x0, x0\n"
284 " b set_point4\n"
285 "0:\n"
286 " mov %[ok], #1\n"
287 " b 1f\n"
288 "set_point4:\n"
289 " tbz x0, #3, 0b\n"
290 " mov %[ok], #0\n"
291 "1:\n"
292 : [ok] "=r" (ok)
293 :
294 : "0");
295
296 if (ok == 1)
297 pass ();
298 else
299 fail ();
300}
301
302/* Make sure we can relocate a TBNZ instruction.
303
304 MOV x0, #8 ; Set bit 3.
305 B set_point5
306 set_ok:
307 MOV %[ok], #1
308 B end
309 set_point5:
310 TBNZ x0, #3, set_ok ; tracepoint here.
311 MOV %[ok], #0
312 end
313
314 */
315
316static void
317can_relocate_tbnz (void)
318{
319 int ok = 0;
320
321 asm (" mov x0, #8\n"
322 " b set_point5\n"
323 "0:\n"
324 " mov %[ok], #1\n"
325 " b 1f\n"
326 "set_point5:\n"
327 " tbnz x0, #3, 0b\n"
328 " mov %[ok], #0\n"
329 "1:\n"
330 : [ok] "=r" (ok)
331 :
332 : "0");
333
334 if (ok == 1)
335 pass ();
336 else
337 fail ();
338}
339
340/* Make sure we can relocate an ADR instruction with a positive offset.
341
342 set_point6:
343 ADR x0, target ; tracepoint here.
344 BR x0 ; jump to target
345 MOV %[ok], #0
346 B end
347 target:
348 MOV %[ok], #1
349 end
350
351 */
352
353static void
354can_relocate_adr_forward (void)
355{
356 int ok = 0;
357
358 asm ("set_point6:\n"
359 " adr x0, 0f\n"
360 " br x0\n"
361 " mov %[ok], #0\n"
362 " b 1f\n"
363 "0:\n"
364 " mov %[ok], #1\n"
365 "1:\n"
366 : [ok] "=r" (ok)
367 :
368 : "0");
369
370 if (ok == 1)
371 pass ();
372 else
373 fail ();
374}
375
376/* Make sure we can relocate an ADR instruction with a negative offset.
377
378 B set_point7
379 target:
380 MOV %[ok], #1
381 B end
382 set_point7:
383 ADR x0, target ; tracepoint here.
384 BR x0 ; jump to target
385 MOV %[ok], #0
386 end
387
388 */
389
390static void
391can_relocate_adr_backward (void)
392{
393 int ok = 0;
394
395 asm ("b set_point7\n"
396 "0:\n"
397 " mov %[ok], #1\n"
398 " b 1f\n"
399 "set_point7:\n"
400 " adr x0, 0b\n"
401 " br x0\n"
402 " mov %[ok], #0\n"
403 "1:\n"
404 : [ok] "=r" (ok)
405 :
406 : "0");
407
408 if (ok == 1)
409 pass ();
410 else
411 fail ();
412}
413
414/* Make sure we can relocate an ADRP instruction.
415
416 set_point8:
417 ADRP %[addr], set_point8 ; tracepoint here.
418 ADR %[pc], set_point8
419
420 ADR computes the address of the given label. While ADRP gives us its
421 page, on a 4K boundary. We can check ADRP executed normally by
422 making sure the result of ADR and ADRP are equivalent, except for the
423 12 lowest bits which should be cleared.
424
425 */
426
427static void
428can_relocate_adrp (void)
429{
430 uintptr_t page;
431 uintptr_t pc;
432
433 asm ("set_point8:\n"
434 " adrp %[page], set_point8\n"
435 " adr %[pc], set_point8\n"
436 : [page] "=r" (page), [pc] "=r" (pc));
437
438 if (page == (pc & ~0xfff))
439 pass ();
440 else
441 fail ();
442}
443
444/* Make sure we can relocate an LDR instruction, where the memory to
445 read is an offset from the current PC.
446
447 B set_point9
448 data:
449 .word 0x0cabba9e
450 set_point9:
451 LDR %[result], data ; tracepoint here.
452
453 */
454
455static void
456can_relocate_ldr (void)
457{
458 uint32_t result = 0;
459
460 asm ("b set_point9\n"
461 "0:\n"
462 " .word 0x0cabba9e\n"
463 "set_point9:\n"
464 " ldr %w[result], 0b\n"
465 : [result] "=r" (result));
466
467 if (result == 0x0cabba9e)
468 pass ();
469 else
470 fail ();
471}
8240f442
YQ
472
473/* Make sure we can relocate a B.cond instruction and condition is false. */
474
475static void
476can_relocate_bcond_false (void)
477{
478 int ok = 0;
479
480 asm (" mov x0, #8\n"
481 " tst x0, #8\n" /* Clear the Z flag. */
482 "set_point10:\n" /* Set tracepoint here. */
483 " b.eq 0b\n" /* Condition is false. */
484 " mov %[ok], #1\n"
485 " b 1f\n"
486 "0:\n"
487 " mov %[ok], #0\n"
488 "1:\n"
489 : [ok] "=r" (ok)
490 :
491 : "0", "cc");
492
493 if (ok == 1)
494 pass ();
495 else
496 fail ();
497}
498
499static void
500foo (void)
501{
502}
503
504/* Make sure we can relocate a BL instruction. */
505
506static void
507can_relocate_bl (void)
508{
509 asm ("set_point11:\n"
510 " bl foo\n"
511 " bl pass\n"); /* Test that LR is updated correctly. */
512}
513
4f51c22a
PL
514#endif
515
516/* Functions testing relocations need to be placed here. GDB will read
517 n_testcases to know how many fast tracepoints to place. It will look
518 for symbols in the form of 'set_point\[0-9\]+' so each functions
519 needs one, starting at 0. */
520
521static testcase_ftype testcases[] = {
522#if (defined __x86_64__ || defined __i386__)
523 can_relocate_call,
524 can_relocate_jump
525#elif (defined __aarch64__)
526 can_relocate_b,
8240f442 527 can_relocate_bcond_true,
4f51c22a
PL
528 can_relocate_cbz,
529 can_relocate_cbnz,
530 can_relocate_tbz,
531 can_relocate_tbnz,
532 can_relocate_adr_forward,
533 can_relocate_adr_backward,
534 can_relocate_adrp,
8240f442
YQ
535 can_relocate_ldr,
536 can_relocate_bcond_false,
537 can_relocate_bl,
4f51c22a
PL
538#endif
539};
540
541static size_t n_testcases = (sizeof (testcases) / sizeof (testcase_ftype));
542
543int
544main ()
545{
546 int i = 0;
547
548 for (i = 0; i < n_testcases; i++)
549 testcases[i] ();
550
551 return 0;
552}
This page took 0.072765 seconds and 4 git commands to generate.