|
1 /* |
|
2 * Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
3 * All rights reserved. |
|
4 * |
|
5 * This program is free software: you can redistribute it and/or modify |
|
6 * it under the terms of the GNU Lesser 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 Lesser General Public License for more details. |
|
14 * |
|
15 * You should have received a copy of the GNU Lesser General Public License |
|
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. |
|
17 */ |
|
18 |
|
19 #include <string.h> |
|
20 #include <iostream> |
|
21 #include <cassert> |
|
22 |
|
23 #include "dwarfmanager.h" |
|
24 #include "inputfile.h" |
|
25 |
|
26 const string DwarfInfoManager::iInfoSectionName(".debug_info"); |
|
27 |
|
28 void DwarfInfoManager::ProcessSection(FileShdrPair & aPair, Dwarf_Byte_Ptr aStart, Dwarf_Byte_Ptr aEnd){ |
|
29 iDwarfAbbrevManager.StartContext(aPair.iXIPFileDetails.iElfFile); |
|
30 Dwarf_Byte_Ptr p = aStart; |
|
31 Dwarf_Byte_Ptr e = aEnd; |
|
32 while (p < e) { |
|
33 p = ProcessCU(aPair, p, e); |
|
34 } |
|
35 iDwarfAbbrevManager.EndContext(); |
|
36 } |
|
37 |
|
38 #define READ_DWARF_VAL(v,t,p) t v = *((t *)p); p += sizeof(t); |
|
39 Dwarf_Byte_Ptr DwarfInfoManager::ProcessCU(FileShdrPair & aPair, Dwarf_Byte_Ptr s, Dwarf_Byte_Ptr e){ |
|
40 Dwarf_Byte_Ptr p = s; |
|
41 //Read the CU header info |
|
42 // first check whether we're dealing with 32bit or 64 bit DWARF |
|
43 |
|
44 // TODO: must abstract over base types e.g uint32 etc. |
|
45 // TODO: this might not be 4 byte aligned and so could cause problems on some |
|
46 // architectures |
|
47 READ_DWARF_VAL(len, Uint32, p); |
|
48 if (len >= 0xfffffff0u){ |
|
49 cerr << "Error: 64 bit DWARF not supported\n"; |
|
50 exit(EXIT_FAILURE); |
|
51 } |
|
52 iLocalLength = len; |
|
53 Dwarf_Byte_Ptr end = p + len; |
|
54 // TODO: make sensitive to dwarf version number? |
|
55 READ_DWARF_VAL(version, Dwarf_Half, p); |
|
56 Uint32 abbrevOffset = *((Uint32 *)p); |
|
57 // update the offset into the abbrev table |
|
58 *((Uint32 *)p) = (Uint32)(abbrevOffset + iDwarfAbbrevManager.GetContextSectionOffset()); |
|
59 p += sizeof(Uint32); |
|
60 READ_DWARF_VAL(address_size, Byte, p); |
|
61 |
|
62 // TODO: if this isn't 4 we're doomed aren't we? |
|
63 iAddressSize = address_size; |
|
64 |
|
65 iDwarfAbbrevManager.SetContextAbbrevOffset(abbrevOffset); |
|
66 |
|
67 // now process each DIE until end. |
|
68 while (p < end) { |
|
69 p = ProcessDIE(aPair, p, end); |
|
70 } |
|
71 |
|
72 return p; |
|
73 } |
|
74 |
|
75 void NoteProducer(FileShdrPair & aPair, Dwarf_Byte_Ptr aPtr, Dwarf_Unsigned aForm){ |
|
76 |
|
77 switch (aForm){ |
|
78 case DW_FORM_string:{ |
|
79 const char * producer = (const char *)aPtr; |
|
80 const char * RvctProducer = "ARM/Thumb C/C++ Compiler, RVCT"; |
|
81 const size_t RvctProducerLength = strlen(RvctProducer); |
|
82 const char * GccProducer = "GNU C++"; |
|
83 const size_t GccProducerLength = strlen(GccProducer); |
|
84 if (!strncmp(producer, RvctProducer, RvctProducerLength)) |
|
85 aPair.iXIPFileDetails.iRVCTProduced = true; |
|
86 if (!strncmp(producer, GccProducer, GccProducerLength)) |
|
87 aPair.iXIPFileDetails.iGCCProduced = true; |
|
88 return; |
|
89 } |
|
90 case DW_FORM_indirect: { |
|
91 size_t indir_len = 0; |
|
92 Dwarf_Unsigned form_indirect = DwarfSectionManager::DecodeUnsignedLeb128(aPtr, indir_len); |
|
93 if (form_indirect == DW_FORM_indirect) { |
|
94 /* Eek, should never happen, will get warned later */ |
|
95 return; |
|
96 } |
|
97 return NoteProducer(aPair, aPtr+indir_len, form_indirect); |
|
98 } |
|
99 case DW_FORM_strp: |
|
100 // TODO - We need to get the string table for this -- |
|
101 return; |
|
102 } |
|
103 } |
|
104 |
|
105 Dwarf_Byte_Ptr DwarfInfoManager::ProcessDIE(FileShdrPair & aPair, Dwarf_Byte_Ptr s, Dwarf_Byte_Ptr e){ |
|
106 Dwarf_Byte_Ptr info_ptr = s; |
|
107 size_t leb128_length; |
|
108 |
|
109 Dwarf_Word abbrev_code = DecodeUnsignedLeb128(info_ptr, leb128_length); |
|
110 info_ptr += leb128_length; |
|
111 if (abbrev_code == 0) { |
|
112 return info_ptr; |
|
113 } |
|
114 |
|
115 DebugAbbrev & abbrev = iDwarfAbbrevManager.GetAbbrev(abbrev_code); |
|
116 |
|
117 //cout << "Tag = " << GetDwarfTag(abbrev.iTag) << " Code = " << abbrev_code << " num attrs = " << abbrev.iCount << endl; |
|
118 |
|
119 for (size_t i = 0; i < abbrev.iCount; i++){ |
|
120 size_t attr = abbrev.iParsed[i].iAttr; |
|
121 Dwarf_Unsigned form = abbrev.iParsed[i].iForm; |
|
122 //cout << "\tAttr " << GetDwarfAttr(attr) << " Form " << GetDwarfForm(form) << "\n"; |
|
123 |
|
124 // record anything interesting about the producer here. |
|
125 if (attr == DW_AT_producer) |
|
126 NoteProducer(aPair, info_ptr, form); |
|
127 |
|
128 if (attr > DW_AT_recursive) |
|
129 info_ptr = DefaultInfoEditFn(*this, info_ptr, form, aPair); |
|
130 else |
|
131 info_ptr = iInfoEditFn[attr](*this, info_ptr, form, aPair); |
|
132 } |
|
133 |
|
134 return info_ptr; |
|
135 } |
|
136 |
|
137 |
|
138 size_t DwarfInfoManager::SizeOfDieValue(Dwarf_Half aForm, Dwarf_Byte_Ptr aPtr){ |
|
139 Dwarf_Unsigned length = 0; |
|
140 size_t leb128_length = 0; |
|
141 size_t ret_value = 0; |
|
142 |
|
143 switch (aForm) { |
|
144 |
|
145 default: /* Handles form = 0. */ |
|
146 return (aForm); |
|
147 |
|
148 case DW_FORM_addr: |
|
149 return iAddressSize; |
|
150 |
|
151 case DW_FORM_ref_addr: |
|
152 // TODO: sort this out |
|
153 return 4; // this is a 4 byte relocatable in 32 bit dwarf and 8-byte in 64 bit dwarf |
|
154 |
|
155 case DW_FORM_block1: |
|
156 return (*aPtr) + 1; |
|
157 |
|
158 case DW_FORM_block2: |
|
159 ret_value = READ_UNALIGNED2(aPtr) + 2; |
|
160 return ret_value; |
|
161 |
|
162 case DW_FORM_block4: |
|
163 ret_value = READ_UNALIGNED4(aPtr) + 4; |
|
164 return ret_value; |
|
165 |
|
166 case DW_FORM_data1: |
|
167 return 1; |
|
168 |
|
169 case DW_FORM_data2: |
|
170 return 2; |
|
171 |
|
172 case DW_FORM_data4: |
|
173 return 4; |
|
174 |
|
175 case DW_FORM_data8: |
|
176 return 8; |
|
177 |
|
178 case DW_FORM_string: |
|
179 return (strlen((char *) aPtr) + 1); |
|
180 |
|
181 case DW_FORM_block: |
|
182 length = DecodeUnsignedLeb128(aPtr, leb128_length); |
|
183 return length + leb128_length; |
|
184 |
|
185 case DW_FORM_flag: |
|
186 return 1; |
|
187 |
|
188 case DW_FORM_ref_udata: |
|
189 DecodeUnsignedLeb128(aPtr, leb128_length); |
|
190 return leb128_length; |
|
191 |
|
192 case DW_FORM_indirect: { |
|
193 size_t indir_len = 0; |
|
194 Dwarf_Unsigned form_indirect = DecodeUnsignedLeb128(aPtr, indir_len); |
|
195 if (form_indirect == DW_FORM_indirect) { |
|
196 /* Eek, should never happen */ |
|
197 cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n"; |
|
198 } |
|
199 return indir_len + SizeOfDieValue(form_indirect, aPtr+indir_len); |
|
200 } |
|
201 |
|
202 case DW_FORM_ref1: |
|
203 return 1; |
|
204 |
|
205 case DW_FORM_ref2: |
|
206 return 2; |
|
207 |
|
208 case DW_FORM_ref4: |
|
209 return 4; |
|
210 |
|
211 case DW_FORM_ref8: |
|
212 return 8; |
|
213 |
|
214 case DW_FORM_sdata: |
|
215 DecodeSignedLeb128(aPtr, leb128_length); |
|
216 return leb128_length; |
|
217 |
|
218 case DW_FORM_strp: |
|
219 // TODO: sort this out |
|
220 return 4; // this is a 4 byte relocatable in 32 bit dwarf and 8-byte in 64 bit dwarf |
|
221 |
|
222 case DW_FORM_udata: |
|
223 DecodeUnsignedLeb128(aPtr, leb128_length); |
|
224 return leb128_length; |
|
225 } |
|
226 } |
|
227 |
|
228 Dwarf_Byte_Ptr DwarfInfoManager::DefaultInfoEditFn(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){ |
|
229 return aPtr + aManager.SizeOfDieValue(aForm, aPtr); |
|
230 } |
|
231 |
|
232 Dwarf_Byte_Ptr DwarfInfoManager::ErrorInfoEditFn(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){ |
|
233 cerr << "Error: Undefined DW_FORM value: " << aForm << "\n" ; |
|
234 exit(EXIT_FAILURE); |
|
235 return aPtr; |
|
236 } |
|
237 |
|
238 // TODO: implicitly only deals with 32-bit DWARF |
|
239 // Called from other edit functions to deal with blocks that contain location expressions. |
|
240 Dwarf_Byte_Ptr DwarfInfoManager::InfoEditLocExpr(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){ |
|
241 Dwarf_Unsigned length = 0; |
|
242 bool locExpr = false; |
|
243 Dwarf_Byte_Ptr block = aPtr; |
|
244 if (aForm == DW_FORM_block1) { |
|
245 locExpr = true; |
|
246 length = block[0]; |
|
247 block++; |
|
248 aPtr += (length + 1); |
|
249 } else if (aForm == DW_FORM_block2) { |
|
250 locExpr = true; |
|
251 length = READ_UNALIGNED2(block); |
|
252 block += 2; |
|
253 aPtr += (length + 2); |
|
254 } else if (aForm == DW_FORM_block4) { |
|
255 locExpr = true; |
|
256 length = READ_UNALIGNED4(block); |
|
257 block += 4; |
|
258 aPtr += (length + 4); |
|
259 } else if (aForm == DW_FORM_block) { |
|
260 locExpr = true; |
|
261 size_t leb_length = 0; |
|
262 length = DecodeUnsignedLeb128(block, leb_length); |
|
263 block += leb_length; |
|
264 aPtr += (length + leb_length); |
|
265 } |
|
266 |
|
267 if (locExpr){ |
|
268 EditLocationExpression (block, aManager.iAddressSize, length, aPair); |
|
269 return aPtr; |
|
270 } else if (aForm == DW_FORM_indirect){ |
|
271 size_t indir_len = 0; |
|
272 Dwarf_Half form_indirect = DecodeUnsignedLeb128(aPtr, indir_len); |
|
273 if (form_indirect == DW_FORM_indirect) { |
|
274 /* Eek, should never happen */ |
|
275 cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n"; |
|
276 } |
|
277 return InfoEditLocExpr(aManager, aPtr+indir_len, form_indirect, aPair); |
|
278 |
|
279 } else |
|
280 return aPtr + aManager.SizeOfDieValue(aForm, aPtr); |
|
281 } |
|
282 // TODO: implicitly only deals with 32-bit DWARF |
|
283 Dwarf_Byte_Ptr DwarfInfoManager::InfoEditAddress(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){ |
|
284 if (aForm == DW_FORM_addr){ |
|
285 LinearAddr addr = READ_UNALIGNED4(aPtr); |
|
286 LinearAddr relocatedAddr = aPair.iXIPFileDetails.Relocate(addr); |
|
287 WRITE_UNALIGNED4(aPtr, relocatedAddr); |
|
288 return aPtr + 4; |
|
289 } else if (aForm == DW_FORM_indirect){ |
|
290 size_t indir_len = 0; |
|
291 Dwarf_Unsigned form_indirect = DecodeUnsignedLeb128(aPtr, indir_len); |
|
292 if (form_indirect == DW_FORM_indirect) { |
|
293 /* Eek, should never happen */ |
|
294 cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n"; |
|
295 } |
|
296 return InfoEditAddress(aManager, aPtr+indir_len, form_indirect, aPair); |
|
297 |
|
298 } else |
|
299 return aPtr + aManager.SizeOfDieValue(aForm, aPtr); |
|
300 } |
|
301 |
|
302 // TODO: implicitly only deals with 32-bit DWARF |
|
303 Dwarf_Byte_Ptr DwarfInfoManager::InfoEditLinePtr(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){ |
|
304 if (aForm == DW_FORM_data4){ |
|
305 size_t offset = READ_UNALIGNED4(aPtr); |
|
306 size_t newOffset = aManager.iDwarfManager.GetLineSectionOffset(aPair.iXIPFileDetails.iElfFile) + offset; |
|
307 if (offset != newOffset) |
|
308 WRITE_UNALIGNED4(aPtr, newOffset); |
|
309 return aPtr + 4; |
|
310 } else if (aForm == DW_FORM_indirect){ |
|
311 size_t indir_len = 0; |
|
312 Dwarf_Half form_indirect = DecodeUnsignedLeb128(aPtr, indir_len); |
|
313 if (form_indirect == DW_FORM_indirect) { |
|
314 /* Eek, should never happen */ |
|
315 cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n"; |
|
316 } |
|
317 return InfoEditLinePtr(aManager, aPtr+indir_len, form_indirect, aPair); |
|
318 |
|
319 } else |
|
320 return aPtr + aManager.SizeOfDieValue(aForm, aPtr); |
|
321 } |
|
322 |
|
323 // TODO: implicitly only deals with 32-bit DWARF |
|
324 Dwarf_Byte_Ptr DwarfInfoManager::InfoEditLocListPtr(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){ |
|
325 if (aForm == DW_FORM_data4){ |
|
326 size_t offset = READ_UNALIGNED4(aPtr); |
|
327 size_t newOffset = aManager.iDwarfManager.GetLocListSectionOffset(aPair.iXIPFileDetails.iElfFile) + offset; |
|
328 if (offset != newOffset) |
|
329 WRITE_UNALIGNED4(aPtr, newOffset); |
|
330 return aPtr + 4; |
|
331 } else if (aForm == DW_FORM_indirect){ |
|
332 size_t indir_len = 0; |
|
333 Dwarf_Half form_indirect = DecodeUnsignedLeb128(aPtr, indir_len); |
|
334 if (form_indirect == DW_FORM_indirect) { |
|
335 /* Eek, should never happen */ |
|
336 cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n"; |
|
337 } |
|
338 return InfoEditLocListPtr(aManager, aPtr+indir_len, form_indirect, aPair); |
|
339 |
|
340 } else |
|
341 //return aPtr + aManager.SizeOfDieValue(aForm, aPtr); |
|
342 return InfoEditLocExpr(aManager, aPtr, aForm, aPair); |
|
343 } |
|
344 |
|
345 |
|
346 |
|
347 |
|
348 |
|
349 // TODO: implicitly only deals with 32-bit DWARF |
|
350 Dwarf_Byte_Ptr DwarfInfoManager::InfoEditMacInfoPtr(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){ |
|
351 if (aForm == DW_FORM_data4){ |
|
352 size_t offset = READ_UNALIGNED4(aPtr); |
|
353 size_t newOffset = aManager.iDwarfManager.GetMacInfoSectionOffset(aPair.iXIPFileDetails.iElfFile) + offset; |
|
354 if (offset != newOffset) |
|
355 WRITE_UNALIGNED4(aPtr, newOffset); |
|
356 return aPtr + 4; |
|
357 } else if (aForm == DW_FORM_indirect){ |
|
358 size_t indir_len = 0; |
|
359 Dwarf_Half form_indirect = DecodeUnsignedLeb128(aPtr, indir_len); |
|
360 if (form_indirect == DW_FORM_indirect) { |
|
361 /* Eek, should never happen */ |
|
362 cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n"; |
|
363 } |
|
364 return InfoEditMacInfoPtr(aManager, aPtr+indir_len, form_indirect, aPair); |
|
365 |
|
366 } else |
|
367 return aPtr + aManager.SizeOfDieValue(aForm, aPtr); |
|
368 } |
|
369 |
|
370 // TODO: implicitly only deals with 32-bit DWARF |
|
371 Dwarf_Byte_Ptr DwarfInfoManager::InfoEditRangeListPtr(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){ |
|
372 if (aForm == DW_FORM_data4){ |
|
373 size_t offset = READ_UNALIGNED4(aPtr); |
|
374 size_t newOffset = aManager.iDwarfManager.GetRangesSectionOffset(aPair.iXIPFileDetails.iElfFile) + offset; |
|
375 if (offset != newOffset) |
|
376 WRITE_UNALIGNED4(aPtr, newOffset); |
|
377 return aPtr + 4; |
|
378 } else if (aForm == DW_FORM_indirect){ |
|
379 size_t indir_len = 0; |
|
380 Dwarf_Half form_indirect = DecodeUnsignedLeb128(aPtr, indir_len); |
|
381 if (form_indirect == DW_FORM_indirect) { |
|
382 /* Eek, should never happen */ |
|
383 cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n"; |
|
384 } |
|
385 return InfoEditRangeListPtr(aManager, aPtr+indir_len, form_indirect, aPair); |
|
386 |
|
387 } else |
|
388 return aPtr + aManager.SizeOfDieValue(aForm, aPtr); |
|
389 } |
|
390 |
|
391 // TODO: implicitly only deals with 32-bit DWARF |
|
392 Dwarf_Byte_Ptr DwarfInfoManager::InfoEditString(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){ |
|
393 |
|
394 if (aForm == DW_FORM_strp){ |
|
395 size_t offset = READ_UNALIGNED4(aPtr); |
|
396 size_t newOffset = aManager.iDwarfManager.GetStrSectionOffset(aPair.iXIPFileDetails.iElfFile) + offset; |
|
397 if (offset != newOffset) |
|
398 WRITE_UNALIGNED4(aPtr, newOffset); |
|
399 return aPtr + 4; |
|
400 } else if (aForm == DW_FORM_indirect){ |
|
401 size_t indir_len = 0; |
|
402 Dwarf_Half form_indirect = DecodeUnsignedLeb128(aPtr, indir_len); |
|
403 if (form_indirect == DW_FORM_indirect) { |
|
404 /* Eek, should never happen */ |
|
405 cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n"; |
|
406 } |
|
407 return InfoEditString(aManager, aPtr+indir_len, form_indirect, aPair); |
|
408 |
|
409 } else |
|
410 return aPtr + aManager.SizeOfDieValue(aForm, aPtr); |
|
411 } |
|
412 |
|
413 // TODO: implicitly only deals with 32-bit DWARF |
|
414 Dwarf_Byte_Ptr DwarfInfoManager::InfoEditReference(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){ |
|
415 if (aForm == DW_FORM_ref_addr){ |
|
416 size_t offset = READ_UNALIGNED4(aPtr); |
|
417 size_t newOffset = aManager.CheckNewOffset(aManager.GetSectionOffset(aPair.iXIPFileDetails.iElfFile), offset); |
|
418 if (offset != newOffset) |
|
419 WRITE_UNALIGNED4(aPtr, newOffset); |
|
420 return aPtr + 4; |
|
421 } else if (aForm == DW_FORM_indirect){ |
|
422 size_t indir_len = 0; |
|
423 Dwarf_Half form_indirect = DecodeUnsignedLeb128(aPtr, indir_len); |
|
424 if (form_indirect == DW_FORM_indirect) { |
|
425 /* Eek, should never happen */ |
|
426 cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n"; |
|
427 } |
|
428 return InfoEditReference(aManager, aPtr+indir_len, form_indirect, aPair); |
|
429 |
|
430 } else |
|
431 //return aPtr + aManager.SizeOfDieValue(aForm, aPtr); |
|
432 return InfoEditLocExpr(aManager, aPtr, aForm, aPair); |
|
433 } |
|
434 |
|
435 // TODO: implicitly only deals with 32-bit DWARF |
|
436 // Explicitly check for *_address and *_strp then let the reference handler deal with the flag possiblity as s 'else'. |
|
437 Dwarf_Byte_Ptr DwarfInfoManager::InfoEditTrampoline(DwarfInfoManager& aManager, Dwarf_Byte_Ptr aPtr, Dwarf_Half aForm, FileShdrPair & aPair){ |
|
438 if (aForm == DW_FORM_addr) |
|
439 return InfoEditAddress(aManager, aPtr, aForm, aPair); |
|
440 else if (aForm = DW_FORM_strp) |
|
441 return InfoEditString(aManager, aPtr, aForm, aPair); |
|
442 else if (aForm == DW_FORM_indirect){ |
|
443 size_t indir_len = 0; |
|
444 Dwarf_Half form_indirect = DecodeUnsignedLeb128(aPtr, indir_len); |
|
445 if (form_indirect == DW_FORM_indirect) { |
|
446 /* Eek, should never happen */ |
|
447 cerr << "Error: DW_FORM_indirect gone recursive! Can't happen\n"; |
|
448 } |
|
449 return InfoEditTrampoline(aManager, aPtr+indir_len, form_indirect, aPair); |
|
450 |
|
451 } |
|
452 else |
|
453 return InfoEditReference(aManager, aPtr, aForm, aPair); |
|
454 } |
|
455 |
|
456 |
|
457 DwarfInfoManager::InfoEditFn DwarfInfoManager::iInfoEditFn [] = { |
|
458 DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 0 so this should never be called |
|
459 DwarfInfoManager::InfoEditReference, // DW_AT_sibling 0x01 |
|
460 DwarfInfoManager::InfoEditLocListPtr, // DW_AT_location 0x02 |
|
461 DwarfInfoManager::InfoEditString, // DW_AT_name 0x03 |
|
462 DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 4 so this should never be called |
|
463 DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 5 so this should never be called |
|
464 DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 6 so this should never be called |
|
465 DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 7 so this should never be called |
|
466 DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 8 so this should never be called |
|
467 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_ordering 0x09 |
|
468 // TODO: This doesn't appear in the DWARF 3 spec of 2005/12/05 :-( so just defualt it for now |
|
469 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_subscr_data 0x0a |
|
470 DwarfInfoManager::InfoEditReference, // DW_AT_byte_size 0x0b |
|
471 DwarfInfoManager::InfoEditReference, // DW_AT_bit_offset 0x0c |
|
472 DwarfInfoManager::InfoEditReference, // DW_AT_bit_size 0x0d |
|
473 DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 0x0e so this should never be called |
|
474 // TODO: This doesn't appear in the DWARF 3 spec of 2005/12/05 :-( so just defualt it for now |
|
475 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_element_list 0x0f |
|
476 DwarfInfoManager::InfoEditLinePtr, // DW_AT_stmt_list 0x10 |
|
477 DwarfInfoManager::InfoEditAddress, // DW_AT_low_pc 0x11 |
|
478 DwarfInfoManager::InfoEditAddress, // DW_AT_high_pc 0x12 |
|
479 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_language 0x13 |
|
480 // TODO: This doesn't appear in the DWARF 3 spec of 2005/12/05 :-( so just defualt it for now |
|
481 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_member 0x14 |
|
482 DwarfInfoManager::InfoEditReference, // DW_AT_discr 0x15 |
|
483 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_discr_value 0x16 |
|
484 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_visibility 0x17 |
|
485 DwarfInfoManager::InfoEditReference, // DW_AT_import 0x18 |
|
486 DwarfInfoManager::InfoEditLocListPtr, // DW_AT_string_length 0x19 |
|
487 DwarfInfoManager::InfoEditReference, // DW_AT_common_reference 0x1a |
|
488 DwarfInfoManager::InfoEditString, // DW_AT_comp_dir 0x1b |
|
489 DwarfInfoManager::InfoEditString, // DW_AT_const_value 0x1c |
|
490 DwarfInfoManager::InfoEditReference, // DW_AT_containing_type 0x1d |
|
491 DwarfInfoManager::InfoEditReference, // DW_AT_default_value 0x1e |
|
492 DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 0x1f so this should never be called |
|
493 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_inline 0x20 |
|
494 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_is_optional 0x21 |
|
495 DwarfInfoManager::InfoEditReference, // DW_AT_lower_bound 0x22 |
|
496 DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 0x23 so this should never be called |
|
497 DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 0x24 so this should never be called |
|
498 DwarfInfoManager::InfoEditString, // DW_AT_producer 0x25 |
|
499 DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 0x26 so this should never be called |
|
500 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_prototyped 0x27 |
|
501 DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 0x28 so this should never be called |
|
502 DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 0x29 so this should never be called |
|
503 DwarfInfoManager::InfoEditLocListPtr, // DW_AT_return_addr 0x2a |
|
504 DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 0x2b so this should never be called |
|
505 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_start_scope 0x2c |
|
506 DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 0x2d so this should never be called |
|
507 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_bit_stride 0x2e /* DWARF3 name */ |
|
508 DwarfInfoManager::InfoEditReference, // DW_AT_upper_bound 0x2f |
|
509 DwarfInfoManager::ErrorInfoEditFn, // There is no DW_FORM 0x30 so this should never be called |
|
510 DwarfInfoManager::InfoEditReference, // DW_AT_abstract_origin 0x31 |
|
511 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_accessibility 0x32 |
|
512 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_address_class 0x33 |
|
513 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_artificial 0x34 |
|
514 DwarfInfoManager::InfoEditReference, // DW_AT_base_types 0x35 |
|
515 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_calling_convention 0x36 |
|
516 DwarfInfoManager::InfoEditReference, // DW_AT_count 0x37 |
|
517 DwarfInfoManager::InfoEditLocListPtr, // DW_AT_data_member_location 0x38 |
|
518 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_decl_column 0x39 |
|
519 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_decl_file 0x3a |
|
520 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_decl_line 0x3b |
|
521 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_declaration 0x3c |
|
522 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_discr_list 0x3d |
|
523 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_encoding 0x3e |
|
524 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_external 0x3f |
|
525 DwarfInfoManager::InfoEditLocListPtr, // DW_AT_frame_base 0x40 |
|
526 DwarfInfoManager::InfoEditReference, // DW_AT_friend 0x41 |
|
527 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_identifier_case 0x42 |
|
528 DwarfInfoManager::InfoEditMacInfoPtr, // DW_AT_macro_info 0x43 |
|
529 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_namelist_item 0x44 |
|
530 DwarfInfoManager::InfoEditReference, // DW_AT_priority 0x45 |
|
531 DwarfInfoManager::InfoEditLocListPtr, // DW_AT_segment 0x46 |
|
532 DwarfInfoManager::InfoEditReference, // DW_AT_specification 0x47 |
|
533 DwarfInfoManager::InfoEditLocListPtr, // DW_AT_static_link 0x48 |
|
534 DwarfInfoManager::InfoEditReference, // DW_AT_type 0x49 |
|
535 DwarfInfoManager::InfoEditLocListPtr, // DW_AT_use_location 0x4a |
|
536 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_variable_parameter 0x4b |
|
537 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_virtuality 0x4c |
|
538 DwarfInfoManager::InfoEditLocListPtr, // DW_AT_vtable_elem_location 0x4d |
|
539 DwarfInfoManager::InfoEditReference, // DW_AT_allocated 0x4e /* DWARF3 */ |
|
540 DwarfInfoManager::InfoEditReference, // DW_AT_associated 0x4f /* DWARF3 */ |
|
541 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_data_location 0x50 /* DWARF3 */ |
|
542 DwarfInfoManager::InfoEditReference, // DW_AT_byte_stride 0x51 /* DWARF3f */ |
|
543 DwarfInfoManager::InfoEditAddress, // DW_AT_entry_pc 0x52 /* DWARF3 */ |
|
544 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_use_UTF8 0x53 /* DWARF3 */ |
|
545 DwarfInfoManager::InfoEditReference, // DW_AT_extension 0x54 /* DWARF3 */ |
|
546 DwarfInfoManager::InfoEditRangeListPtr, // DW_AT_ranges 0x55 /* DWARF3 */ |
|
547 DwarfInfoManager::InfoEditTrampoline, // DW_AT_trampoline 0x56 /* DWARF3 */ |
|
548 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_call_column 0x57 /* DWARF3 */ |
|
549 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_call_file 0x58 /* DWARF3 */ |
|
550 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_call_line 0x59 /* DWARF3 */ |
|
551 DwarfInfoManager::InfoEditString, // DW_AT_description 0x5a /* DWARF3 */ |
|
552 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_binary_scale 0x5b /* DWARF3f */ |
|
553 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_decimal_scale 0x5c /* DWARF3f */ |
|
554 DwarfInfoManager::InfoEditReference, // DW_AT_small 0x5d /* DWARF3f */ |
|
555 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_decimal_sign 0x5e /* DWARF3f */ |
|
556 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_digit_count 0x5f /* DWARF3f */ |
|
557 DwarfInfoManager::InfoEditString, // DW_AT_picture_string 0x60 /* DWARF3f */ |
|
558 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_mutable 0x61 /* DWARF3f */ |
|
559 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_threads_scaled 0x62 /* DWARF3f */ |
|
560 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_explicit 0x63 /* DWARF3f */ |
|
561 DwarfInfoManager::InfoEditReference, // DW_AT_object_pointer 0x64 /* DWARF3f */ |
|
562 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_endianity 0x65 /* DWARF3f */ |
|
563 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_elemental 0x66 /* DWARF3f */ |
|
564 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_pure 0x67 /* DWARF3f */ |
|
565 DwarfInfoManager::DefaultInfoEditFn, // DW_AT_recursive 0x68 /* DWARF3f */ |
|
566 }; |