xref: /netbsd-src/external/gpl3/gdb.old/dist/gdb/testsuite/gdb.dwarf2/dw2-inline-many-frames.c (revision d16b7486a53dcb8072b60ec6fcb4373a2d0c27b7)
1 /* Copyright 2019-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 
16 /* This test sets up a call stack that looks like this:
17 
18    #11     #10    #9     #8     #7     #6     #5     #4     #3     #2     #1     #0
19    main -> aaa -> bbb -> ccc -> ddd -> eee -> fff -> ggg -> hhh -> iii -> jjj -> kkk
20    \_______________________/    \________/    \______________________/    \________/
21       Inline sequence #1          Normal          Inline sequence #2        Normal
22 
23    We use the 'start' command to move into main, after that we 'step'
24    through each function until we are in kkk.  We then use the 'up' command
25    to look back at each from to main.
26 
27    The test checks that we can handle and step through sequences of more
28    than one inline frame (so 'main .... ccc', and 'fff .... iii'), and also
29    that we can move around in a stack that contains more than one disjoint
30    sequence of inline frames.
31 
32    The order of the functions in this file is deliberately mixed up so that
33    the line numbers are not "all ascending" or "all descending" in the line
34    table.  */
35 
36 #define INLINE_FUNCTION __attribute__ ((always_inline)) static inline
37 #define NON_INLINE_FUNCTION __attribute__ ((noinline))
38 
39 volatile int global_var = 0;
40 
41 INLINE_FUNCTION int aaa ();
42 INLINE_FUNCTION int bbb ();
43 INLINE_FUNCTION int ccc ();
44 
45 NON_INLINE_FUNCTION int ddd ();
46 NON_INLINE_FUNCTION int eee ();
47 NON_INLINE_FUNCTION int fff ();
48 
49 INLINE_FUNCTION int ggg ();
50 INLINE_FUNCTION int hhh ();
51 INLINE_FUNCTION int iii ();
52 
53 NON_INLINE_FUNCTION int jjj ();
54 NON_INLINE_FUNCTION int kkk ();
55 
56 INLINE_FUNCTION int
57 aaa ()
58 {						/* aaa prologue */
59   asm ("aaa_label: .globl aaa_label");
60   return bbb () + 1;				/* aaa return */
61 }						/* aaa end */
62 
63 NON_INLINE_FUNCTION int
64 jjj ()
65 {						/* jjj prologue */
66   int ans;
67   asm ("jjj_label: .globl jjj_label");
68   ans = kkk () + 1;				/* jjj return */
69   asm ("jjj_label2: .globl jjj_label2");
70   return ans;
71 }						/* jjj end */
72 
73 INLINE_FUNCTION int
74 ggg ()
75 {						/* ggg prologue */
76   asm ("ggg_label: .globl ggg_label");
77   return hhh () + 1;				/* ggg return */
78 }						/* ggg end */
79 
80 INLINE_FUNCTION int
81 ccc ()
82 {						/* ccc prologue */
83   asm ("ccc_label: .globl ccc_label");
84   return ddd () + 1;				/* ccc return */
85 }						/* ccc end */
86 
87 NON_INLINE_FUNCTION int
88 fff ()
89 {						/* fff prologue */
90   int ans;
91   asm ("fff_label: .globl fff_label");
92   ans = ggg () + 1;				/* fff return */
93   asm ("fff_label2: .globl fff_label2");
94   return ans;
95 }						/* fff end */
96 
97 NON_INLINE_FUNCTION int
98 kkk ()
99 {						/* kkk prologue */
100   asm ("kkk_label: .globl kkk_label");
101   return global_var;				/* kkk return */
102 }						/* kkk end */
103 
104 INLINE_FUNCTION int
105 bbb ()
106 {						/* bbb prologue */
107   asm ("bbb_label: .globl bbb_label");
108   return ccc () + 1;				/* bbb return */
109 }						/* bbb end */
110 
111 INLINE_FUNCTION int
112 hhh ()
113 {						/* hhh prologue */
114   asm ("hh_label: .globl hhh_label");
115   return iii () + 1;				/* hhh return */
116 }						/* hhh end */
117 
118 int
119 main ()
120 {						/* main prologue */
121   int ans;
122   asm ("main_label: .globl main_label");
123   global_var = 0;				/* main set global_var */
124   asm ("main_label2: .globl main_label2");
125   ans = aaa () + 1;				/* main call aaa */
126   asm ("main_label3: .globl main_label3");
127   return ans;
128 }						/* main end */
129 
130 NON_INLINE_FUNCTION int
131 ddd ()
132 {						/* ddd prologue */
133   int ans;
134   asm ("ddd_label: .globl ddd_label");
135   ans =  eee () + 1;				/* ddd return */
136   asm ("ddd_label2: .globl ddd_label2");
137   return ans;
138 }						/* ddd end */
139 
140 INLINE_FUNCTION int
141 iii ()
142 {						/* iii prologue */
143   int ans;
144   asm ("iii_label: .globl iii_label");
145   ans = jjj () + 1;				/* iii return */
146   asm ("iii_label2: .globl iii_label2");
147   return ans;
148 }						/* iii end */
149 
150 NON_INLINE_FUNCTION int
151 eee ()
152 {						/* eee prologue */
153   int ans;
154   asm ("eee_label: .globl eee_label");
155   ans = fff () + 1;				/* eee return */
156   asm ("eee_label2: .globl eee_label2");
157   return ans;
158 }						/* eee end */
159