| OLD | NEW |
| (Empty) |
| 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. | |
| OLD | NEW |