]>
Commit | Line | Data |
---|---|---|
c906108c SS |
1 | What's LRS? |
2 | =========== | |
3 | ||
4 | LRS, or Live Range Splitting is an optimization technique which allows | |
5 | a user variable to reside in different locations during different parts | |
6 | of a function. | |
7 | ||
8 | For example, a variable might reside in the stack for part of a function | |
9 | and in a register during a loop and in a different register during | |
10 | another loop. | |
11 | ||
12 | Clearly, if a variable may reside in different locations, then the | |
13 | compiler must describe to the debugger where the variable resides for | |
14 | any given part of the function. | |
15 | ||
16 | This document describes the debug format for encoding these extensions | |
17 | in stabs. | |
18 | ||
19 | Since these extensions are gcc specific, these additional symbols and | |
20 | stabs can be disabled by the gcc command option -gstabs. | |
21 | ||
22 | ||
23 | GNU extensions for LRS under stabs: | |
24 | =================================== | |
25 | ||
26 | ||
27 | range symbols: | |
28 | ------------- | |
29 | ||
30 | A range symbol will be used to mark the beginning or end of a | |
31 | live range (the range which describes where a symbol is active, | |
32 | or live). These symbols will later be referenced in the stabs for | |
33 | debug purposes. For simplicity, we'll use the terms "range_start" | |
34 | and "range_end" to identify the range symbols which mark the beginning | |
35 | and end of a live range respectively. | |
36 | ||
37 | Any text symbol which would normally appear in the symbol table | |
38 | (eg. a function name) can be used as range symbol. If an address | |
39 | is needed to delimit a live range and does not match any of the | |
40 | values of symbols which would normally appear in the symbol table, | |
41 | a new symbol will be added to the table whose value is that address. | |
42 | ||
43 | The three new symbol types described below have been added for this | |
44 | purpose. | |
45 | ||
46 | For efficiency, the compiler should use existing symbols as range | |
47 | symbols whenever possible; this reduces the number of additional | |
48 | symbols which need to be added to the symbol table. | |
49 | ||
50 | ||
51 | New debug symbol type for defining ranges: | |
52 | ------------------------------------------ | |
53 | ||
54 | range_off - contains PC function offset for start/end of a live range. | |
55 | Its location is relative to the function start and therefore | |
56 | eliminates the need for additional relocation. | |
57 | ||
58 | This symbol has a values in the text section, and does not have a name. | |
59 | ||
60 | NOTE: the following may not be needed but are included here just | |
61 | in case. | |
62 | range - contains PC value of beginning or end of a live range | |
63 | (relocs required). | |
64 | ||
65 | NOTE: the following will be required if we desire LRS debugging | |
66 | to work with old style a.out stabs. | |
67 | range_abs - contains absolute PC value of start/end of a live | |
68 | range. The range_abs debug symbol is provided for | |
69 | completeness, in case there is a need to describe addresses | |
70 | in ROM, etc. | |
71 | ||
72 | ||
73 | Live range: | |
74 | ----------- | |
75 | ||
76 | The compiler and debugger view a variable with multiple homes as | |
77 | a primary symbol and aliases for that symbol. The primary symbol | |
78 | describes the default home of the variable while aliases describe | |
79 | alternate homes for the variable. | |
80 | ||
81 | A live range defines the interval of instructions beginning with | |
82 | range_start and ending at range_end-1, and is used to specify a | |
83 | range of instructions where an alias is active or "live". So, | |
84 | the actual end of the range will be one less than the value of the | |
85 | range_end symbol. | |
86 | ||
87 | Ranges do not have to be nested. Eg. Two ranges may intersect while | |
88 | each range contains subranges which are not in the other range. | |
89 | ||
90 | There does not have to be a 1-1 mapping from range_start to | |
91 | range_end symbols. Eg. Two range_starts can share the same | |
92 | range_end, while one symbol's range_start can be another symbol's | |
93 | range_end. | |
94 | ||
95 | When a variable's storage class changes (eg. from stack to register, | |
96 | or from one register to another), a new symbol entry will be | |
97 | added to the symbol table with stabs describing the new type, | |
98 | and appropriate live ranges refering to the variable's initial | |
99 | symbol index. | |
100 | ||
101 | For variables which are defined in the source but optimized away, | |
102 | a symbol should be emitted with the live range l(0,0). | |
103 | ||
104 | Live ranges for aliases of a particular variable should always | |
105 | be disjoint. Overlapping ranges for aliases of the same variable | |
106 | will be treated as an error by the debugger, and the overlapping | |
107 | range will be ignored. | |
108 | ||
109 | If no live range information is given, the live range will be assumed to | |
110 | span the symbol's entire lexical scope. | |
111 | ||
112 | ||
113 | New stabs string identifiers: | |
114 | ----------------------------- | |
115 | ||
116 | "id" in "#id" in the following section refers to a numeric value. | |
117 | ||
118 | New stab syntax for live range: l(<ref_from>,<ref_to>) | |
119 | ||
120 | <ref_from> - "#id" where #id identifies the text symbol (range symbol) to | |
121 | use as the start of live range (range_start). The value for | |
122 | the referenced text symbol is the starting address of the | |
123 | live range. | |
124 | ||
125 | <ref_to> - "#id" where #id identifies the text symbol (range symbol) to | |
126 | use as the end of live range (range_end). The value for | |
127 | the referenced text symbol is ONE BYTE PAST the ending | |
128 | address of the live range. | |
129 | ||
130 | ||
131 | New stab syntax for identifying symbols. | |
132 | ||
133 | <def> - "#id=" | |
134 | ||
135 | Uses: | |
136 | <def><name>:<typedef1>... | |
137 | When used in front of a symbol name, "#id=" defines a | |
138 | unique reference number for this symbol. The reference | |
139 | number can be used later when defining aliases for this | |
140 | symbol. | |
141 | <def> | |
142 | When used as the entire stab string, "#id=" identifies this | |
143 | nameless symbol as being the symbol for which "#id" refers to. | |
144 | ||
145 | ||
146 | <ref> - "#id" where "#id" refers to the symbol for which the string | |
147 | "#id=" identifies. | |
148 | Uses: | |
149 | <ref>:<typedef2>;<liverange>;<liverange>... | |
150 | Defines an alias for the symbol identified by the reference | |
151 | number ID. | |
152 | l(<ref1>,<ref2>) | |
153 | When used within a live range, "#id" refers to the text | |
154 | symbol identified by "#id=" to use as the range symbol. | |
155 | ||
156 | <liverange> - "l(<ref_from>,<ref_to>)" - specifies a live range for a | |
157 | symbol. Multiple "l" specifiers can be combined to represent | |
158 | mutiple live ranges, separated by semicolons. | |
159 | ||
160 | ||
161 | ||
162 | ||
163 | Example: | |
164 | ======== | |
165 | ||
166 | Consider a program of the form: | |
167 | ||
168 | void foo(){ | |
169 | int a = ...; | |
170 | ... | |
171 | while (b--) | |
172 | c += a; | |
173 | .. | |
174 | d = a; | |
175 | .. | |
176 | } | |
177 | ||
178 | Assume that "a" lives in the stack at offset -8, except for inside the | |
179 | loop where "a" resides in register "r5". | |
180 | ||
181 | The way to describe this is to create a stab for the variable "a" which | |
182 | describes "a" as living in the stack and an alias for the variable "a" | |
183 | which describes it as living in register "r5" in the loop. | |
184 | ||
185 | Let's assume that "#1" and "#2" are symbols which bound the area where | |
186 | "a" lives in a register. | |
187 | ||
188 | The stabs to describe "a" and its alias would look like this: | |
189 | ||
190 | .stabs "#3=a:1",128,0,8,-8 | |
191 | .stabs "#3:r1;l(#1,#2)",64,0,0,5 | |
192 | ||
193 | ||
194 | This design implies that the debugger will keep a chain of aliases for | |
195 | any given variable with aliases and that chain will be searched first | |
196 | to find out if an alias is active. If no alias is active, then the | |
197 | debugger will assume that the main variable is active. |