1 1.1 christos /* This testcase is part of GDB, the GNU debugger. 2 1.1 christos 3 1.1 christos Copyright 2024 Free Software Foundation, Inc. 4 1.1 christos 5 1.1 christos This program is free software; you can redistribute it and/or modify 6 1.1 christos it under the terms of the GNU General Public License as published by 7 1.1 christos the Free Software Foundation; either version 3 of the License, or 8 1.1 christos (at your option) any later version. 9 1.1 christos 10 1.1 christos This program is distributed in the hope that it will be useful, 11 1.1 christos but WITHOUT ANY WARRANTY; without even the implied warranty of 12 1.1 christos MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 1.1 christos GNU General Public License for more details. 14 1.1 christos 15 1.1 christos You should have received a copy of the GNU General Public License 16 1.1 christos along with this program. If not, see <http://www.gnu.org/licenses/>. */ 17 1.1 christos 18 1.1 christos /* Used to insert labels within function foo. */ 19 1.1 christos #define LABEL(N) asm ("foo_label_" #N ": .globl foo_label_" #N) 20 1.1 christos 21 1.1 christos volatile int global_var = 0; 22 1.1 christos 23 1.1 christos /* The contents of this '#if 0' block exist so the generated debug can 24 1.1 christos point to these as the source lines. */ 25 1.1 christos #if 0 26 1.1 christos 27 1.1 christos void 28 1.1 christos bar (void) /* bar decl line */ 29 1.1 christos { 30 1.1 christos /* bar line 1 */ 31 1.1 christos /* bar line 2 */ 32 1.1 christos } 33 1.1 christos 34 1.1 christos void 35 1.1 christos baz (void) /* baz decl line */ 36 1.1 christos { 37 1.1 christos /* baz line 1 */ 38 1.1 christos /* baz line 2 */ 39 1.1 christos } 40 1.1 christos 41 1.1 christos void 42 1.1 christos foo (void) /* foo decl line */ 43 1.1 christos { 44 1.1 christos /* foo line 1 */ 45 1.1 christos /* foo line 2 */ 46 1.1 christos /* foo line 3 */ 47 1.1 christos /* foo line 4 */ 48 1.1 christos } 49 1.1 christos 50 1.1 christos #endif 51 1.1 christos 52 1.1 christos extern void *foo_label_6 (void); 53 1.1 christos 54 1.1 christos void 55 1.1 christos foo (void) 56 1.1 christos { 57 1.1 christos /* This label is used to find the start of 'foo' when generating the 58 1.1 christos debug information. */ 59 1.1 christos asm ("foo_label: .globl foo_label"); 60 1.1 christos ++global_var; 61 1.1 christos 62 1.1 christos LABEL (1); 63 1.1 christos ++global_var; 64 1.1 christos 65 1.1 christos LABEL (2); 66 1.1 christos ++global_var; 67 1.1 christos 68 1.1 christos LABEL (3); 69 1.1 christos ++global_var; 70 1.1 christos 71 1.1 christos /* This goto will always trigger, but we make it conditional so that the 72 1.1 christos compiler doesn't optimise out the code between the goto and the 73 1.1 christos destination. 74 1.1 christos 75 1.1 christos Also 'goto *ADDR' is a GCC extension, but it is critical that the 76 1.1 christos destination address be a global label so that we can generate DWARF 77 1.1 christos that has ranges that start exactly at the destination address. */ 78 1.1 christos if (global_var > 0) 79 1.1 christos goto *(&foo_label_6); 80 1.1 christos 81 1.1 christos LABEL (4); 82 1.1 christos ++global_var; 83 1.1 christos 84 1.1 christos LABEL (5); 85 1.1 christos ++global_var; 86 1.1 christos 87 1.1 christos LABEL (6); 88 1.1 christos ++global_var; 89 1.1 christos 90 1.1 christos LABEL (7); 91 1.1 christos ++global_var; 92 1.1 christos 93 1.1 christos LABEL (8); 94 1.1 christos ++global_var; 95 1.1 christos 96 1.1 christos LABEL (9); 97 1.1 christos ++global_var; 98 1.1 christos } 99 1.1 christos 100 1.1 christos int 101 1.1 christos main (void) 102 1.1 christos { 103 1.1 christos asm ("main_label: .globl main_label"); 104 1.1 christos foo (); 105 1.1 christos } 106