|
1 /* |
|
2 |
|
3 Copyright (C) 2000,2002,2004 Silicon Graphics, Inc. All Rights Reserved. |
|
4 Portions Copyright (C) 2007 David Anderson. All Rights Reserved. |
|
5 |
|
6 This program is free software; you can redistribute it and/or modify it |
|
7 under the terms of version 2.1 of the GNU Lesser General Public License |
|
8 as published by the Free Software Foundation. |
|
9 |
|
10 This program is distributed in the hope that it would be useful, but |
|
11 WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
|
13 |
|
14 Further, this software is distributed without any warranty that it is |
|
15 free of the rightful claim of any third person regarding infringement |
|
16 or the like. Any license provided herein, whether implied or |
|
17 otherwise, applies only to this software file. Patent licenses, if |
|
18 any, provided herein do not apply to combinations of this program with |
|
19 other software, or any other product whatsoever. |
|
20 |
|
21 You should have received a copy of the GNU Lesser General Public |
|
22 License along with this program; if not, write the Free Software |
|
23 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, |
|
24 USA. |
|
25 |
|
26 Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, |
|
27 Mountain View, CA 94043, or: |
|
28 |
|
29 http://www.sgi.com |
|
30 |
|
31 For further information regarding this notice, see: |
|
32 |
|
33 http://oss.sgi.com/projects/GenInfo/NoticeExplan |
|
34 |
|
35 */ |
|
36 /* The address of the Free Software Foundation is |
|
37 Free Software Foundation, Inc., 51 Franklin St, Fifth Floor, |
|
38 Boston, MA 02110-1301, USA. |
|
39 SGI has moved from the Crittenden Lane address. |
|
40 */ |
|
41 |
|
42 |
|
43 |
|
44 |
|
45 |
|
46 |
|
47 #include "config.h" |
|
48 #include "dwarf_incl.h" |
|
49 #include <stdio.h> |
|
50 #include "dwarf_arange.h" |
|
51 #include "dwarf_global.h" /* for _dwarf_fixup_* */ |
|
52 |
|
53 |
|
54 /* |
|
55 This function returns the count of the number of |
|
56 aranges in the .debug_aranges section. It sets |
|
57 aranges to point to a block of Dwarf_Arange's |
|
58 describing the arange's. It returns DW_DLV_ERROR |
|
59 on error. |
|
60 |
|
61 Must be identical in most aspects to |
|
62 dwarf_get_aranges_addr_offsets! |
|
63 */ |
|
64 int |
|
65 dwarf_get_aranges(Dwarf_Debug dbg, |
|
66 Dwarf_Arange ** aranges, |
|
67 Dwarf_Signed * returned_count, Dwarf_Error * error) |
|
68 { |
|
69 /* Sweeps the .debug_aranges section. */ |
|
70 Dwarf_Small *arange_ptr = 0; |
|
71 |
|
72 /* |
|
73 Start of arange header. Used for rounding offset of arange_ptr |
|
74 to twice the tuple size. Libdwarf requirement. */ |
|
75 Dwarf_Small *header_ptr = 0; |
|
76 |
|
77 |
|
78 /* Version of .debug_aranges header. */ |
|
79 Dwarf_Half version = 0; |
|
80 |
|
81 /* Offset of current set of aranges into .debug_info. */ |
|
82 Dwarf_Off info_offset = 0; |
|
83 |
|
84 /* Size in bytes of addresses in target. */ |
|
85 Dwarf_Small address_size = 0; |
|
86 |
|
87 /* Size in bytes of segment offsets in target. */ |
|
88 Dwarf_Small segment_size = 0; |
|
89 |
|
90 Dwarf_Small remainder = 0; |
|
91 |
|
92 /* Count of total number of aranges. */ |
|
93 Dwarf_Unsigned arange_count = 0; |
|
94 |
|
95 /* Start address of arange. */ |
|
96 Dwarf_Addr range_address = 0; |
|
97 |
|
98 /* Length of arange. */ |
|
99 Dwarf_Unsigned range_length = 0; |
|
100 |
|
101 Dwarf_Arange arange, *arange_block = 0; |
|
102 |
|
103 Dwarf_Unsigned i = 0; |
|
104 |
|
105 /* Used to chain Dwarf_Aranges structs. */ |
|
106 Dwarf_Chain curr_chain = NULL; |
|
107 Dwarf_Chain prev_chain = NULL; |
|
108 Dwarf_Chain head_chain = NULL; |
|
109 |
|
110 int res = 0; |
|
111 |
|
112 /* ***** BEGIN CODE ***** */ |
|
113 |
|
114 if (dbg == NULL) { |
|
115 _dwarf_error(NULL, error, DW_DLE_DBG_NULL); |
|
116 return (DW_DLV_ERROR); |
|
117 } |
|
118 |
|
119 res = |
|
120 _dwarf_load_section(dbg, |
|
121 dbg->de_debug_aranges_index, |
|
122 &dbg->de_debug_aranges, error); |
|
123 if (res != DW_DLV_OK) { |
|
124 return res; |
|
125 } |
|
126 |
|
127 arange_ptr = dbg->de_debug_aranges; |
|
128 do { |
|
129 /* Length of current set of aranges. */ |
|
130 Dwarf_Unsigned length; |
|
131 Dwarf_Small *arange_ptr_past_end = 0; |
|
132 |
|
133 int local_length_size; |
|
134 |
|
135 /*REFERENCED*/ /* Not used in this instance of the |
|
136 macro */ |
|
137 int local_extension_size; |
|
138 |
|
139 header_ptr = arange_ptr; |
|
140 |
|
141 /* READ_AREA_LENGTH updates arange_ptr for consumed bytes */ |
|
142 READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned, |
|
143 arange_ptr, local_length_size, |
|
144 local_extension_size); |
|
145 arange_ptr_past_end = arange_ptr + length; |
|
146 |
|
147 |
|
148 READ_UNALIGNED(dbg, version, Dwarf_Half, |
|
149 arange_ptr, sizeof(Dwarf_Half)); |
|
150 arange_ptr += sizeof(Dwarf_Half); |
|
151 length = length - sizeof(Dwarf_Half); |
|
152 if (version != CURRENT_VERSION_STAMP) { |
|
153 _dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR); |
|
154 return (DW_DLV_ERROR); |
|
155 } |
|
156 |
|
157 READ_UNALIGNED(dbg, info_offset, Dwarf_Off, |
|
158 arange_ptr, local_length_size); |
|
159 arange_ptr += local_length_size; |
|
160 length = length - local_length_size; |
|
161 if (info_offset >= dbg->de_debug_info_size) { |
|
162 FIX_UP_OFFSET_IRIX_BUG(dbg, info_offset, |
|
163 "arange info offset.a"); |
|
164 if (info_offset >= dbg->de_debug_info_size) { |
|
165 _dwarf_error(dbg, error, DW_DLE_ARANGE_OFFSET_BAD); |
|
166 return (DW_DLV_ERROR); |
|
167 } |
|
168 } |
|
169 |
|
170 address_size = *(Dwarf_Small *) arange_ptr; |
|
171 if (address_size != dbg->de_pointer_size) { |
|
172 /* Internal error of some kind */ |
|
173 _dwarf_error(dbg, error, DW_DLE_BADBITC); |
|
174 return (DW_DLV_ERROR); |
|
175 } |
|
176 arange_ptr = arange_ptr + sizeof(Dwarf_Small); |
|
177 length = length - sizeof(Dwarf_Small); |
|
178 |
|
179 segment_size = *(Dwarf_Small *) arange_ptr; |
|
180 arange_ptr = arange_ptr + sizeof(Dwarf_Small); |
|
181 length = length - sizeof(Dwarf_Small); |
|
182 if (segment_size != 0) { |
|
183 _dwarf_error(dbg, error, DW_DLE_SEGMENT_SIZE_BAD); |
|
184 return (DW_DLV_ERROR); |
|
185 } |
|
186 |
|
187 /* Round arange_ptr offset to next multiple of address_size. */ |
|
188 remainder = (Dwarf_Unsigned) (arange_ptr - header_ptr) % |
|
189 (2 * address_size); |
|
190 if (remainder != 0) { |
|
191 arange_ptr = arange_ptr + (2 * address_size) - remainder; |
|
192 length = length - ((2 * address_size) - remainder); |
|
193 } |
|
194 |
|
195 do { |
|
196 READ_UNALIGNED(dbg, range_address, Dwarf_Addr, |
|
197 arange_ptr, address_size); |
|
198 arange_ptr += address_size; |
|
199 length = length - address_size; |
|
200 |
|
201 READ_UNALIGNED(dbg, range_length, Dwarf_Unsigned, |
|
202 arange_ptr, address_size); |
|
203 arange_ptr += address_size; |
|
204 length = length - address_size; |
|
205 |
|
206 if (range_address != 0 || range_length != 0) { |
|
207 |
|
208 arange = (Dwarf_Arange) |
|
209 _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1); |
|
210 if (arange == NULL) { |
|
211 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); |
|
212 return (DW_DLV_ERROR); |
|
213 } |
|
214 |
|
215 arange->ar_address = range_address; |
|
216 arange->ar_length = range_length; |
|
217 arange->ar_info_offset = info_offset; |
|
218 arange->ar_dbg = dbg; |
|
219 arange_count++; |
|
220 |
|
221 curr_chain = (Dwarf_Chain) |
|
222 _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); |
|
223 if (curr_chain == NULL) { |
|
224 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); |
|
225 return (DW_DLV_ERROR); |
|
226 } |
|
227 |
|
228 curr_chain->ch_item = arange; |
|
229 if (head_chain == NULL) |
|
230 head_chain = prev_chain = curr_chain; |
|
231 else { |
|
232 prev_chain->ch_next = curr_chain; |
|
233 prev_chain = curr_chain; |
|
234 } |
|
235 } |
|
236 } while (range_address != 0 || range_length != 0); |
|
237 |
|
238 /* A compiler could emit some padding bytes here. dwarf2/3 |
|
239 (dwarf3 draft8 sec 7.20) does not clearly make extra padding |
|
240 bytes illegal. */ |
|
241 if (arange_ptr_past_end < arange_ptr) { |
|
242 _dwarf_error(dbg, error, DW_DLE_ARANGE_LENGTH_BAD); |
|
243 return (DW_DLV_ERROR); |
|
244 } |
|
245 /* For most compilers, arange_ptr == arange_ptr_past_end at |
|
246 this point. But not if there were padding bytes */ |
|
247 arange_ptr = arange_ptr_past_end; |
|
248 |
|
249 } while (arange_ptr < |
|
250 dbg->de_debug_aranges + dbg->de_debug_aranges_size); |
|
251 |
|
252 if (arange_ptr != |
|
253 dbg->de_debug_aranges + dbg->de_debug_aranges_size) { |
|
254 _dwarf_error(dbg, error, DW_DLE_ARANGE_DECODE_ERROR); |
|
255 return (DW_DLV_ERROR); |
|
256 } |
|
257 |
|
258 arange_block = (Dwarf_Arange *) |
|
259 _dwarf_get_alloc(dbg, DW_DLA_LIST, arange_count); |
|
260 if (arange_block == NULL) { |
|
261 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); |
|
262 return (DW_DLV_ERROR); |
|
263 } |
|
264 |
|
265 curr_chain = head_chain; |
|
266 for (i = 0; i < arange_count; i++) { |
|
267 *(arange_block + i) = curr_chain->ch_item; |
|
268 prev_chain = curr_chain; |
|
269 curr_chain = curr_chain->ch_next; |
|
270 dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN); |
|
271 } |
|
272 |
|
273 *aranges = arange_block; |
|
274 *returned_count = (arange_count); |
|
275 return DW_DLV_OK; |
|
276 } |
|
277 |
|
278 /* |
|
279 This function returns DW_DLV_OK if it succeeds |
|
280 and DW_DLV_ERR or DW_DLV_OK otherwise. |
|
281 count is set to the number of addresses in the |
|
282 .debug_aranges section. |
|
283 For each address, the corresponding element in |
|
284 an array is set to the address itself(aranges) and |
|
285 the section offset (offsets). |
|
286 Must be identical in most aspects to |
|
287 dwarf_get_aranges! |
|
288 */ |
|
289 int |
|
290 _dwarf_get_aranges_addr_offsets(Dwarf_Debug dbg, |
|
291 Dwarf_Addr ** addrs, |
|
292 Dwarf_Off ** offsets, |
|
293 Dwarf_Signed * count, |
|
294 Dwarf_Error * error) |
|
295 { |
|
296 /* Sweeps the .debug_aranges section. */ |
|
297 Dwarf_Small *arange_ptr = 0; |
|
298 Dwarf_Small *arange_start_ptr = 0; |
|
299 |
|
300 /* |
|
301 Start of arange header. Used for rounding offset of arange_ptr |
|
302 to twice the tuple size. Libdwarf requirement. */ |
|
303 Dwarf_Small *header_ptr = 0; |
|
304 |
|
305 /* Length of current set of aranges. */ |
|
306 Dwarf_Unsigned length = 0; |
|
307 |
|
308 /* Version of .debug_aranges header. */ |
|
309 Dwarf_Half version = 0; |
|
310 |
|
311 /* Offset of current set of aranges into .debug_info. */ |
|
312 Dwarf_Off info_offset = 0; |
|
313 |
|
314 /* Size in bytes of addresses in target. */ |
|
315 Dwarf_Small address_size = 0; |
|
316 |
|
317 /* Size in bytes of segment offsets in target. */ |
|
318 Dwarf_Small segment_size = 0; |
|
319 |
|
320 Dwarf_Small remainder = 0; |
|
321 |
|
322 /* Count of total number of aranges. */ |
|
323 Dwarf_Unsigned arange_count = 0; |
|
324 |
|
325 /* Start address of arange. */ |
|
326 Dwarf_Addr range_address = 0; |
|
327 |
|
328 /* Length of arange. */ |
|
329 Dwarf_Unsigned range_length = 0; |
|
330 |
|
331 Dwarf_Arange arange = 0; |
|
332 |
|
333 Dwarf_Unsigned i = 0; |
|
334 |
|
335 /* Used to chain Dwarf_Aranges structs. */ |
|
336 Dwarf_Chain curr_chain = NULL; |
|
337 Dwarf_Chain prev_chain = NULL; |
|
338 Dwarf_Chain head_chain = NULL; |
|
339 |
|
340 Dwarf_Addr *arange_addrs = 0; |
|
341 Dwarf_Off *arange_offsets = 0; |
|
342 |
|
343 int res = 0; |
|
344 |
|
345 /* ***** BEGIN CODE ***** */ |
|
346 |
|
347 if (error != NULL) |
|
348 *error = NULL; |
|
349 |
|
350 if (dbg == NULL) { |
|
351 _dwarf_error(NULL, error, DW_DLE_DBG_NULL); |
|
352 return (DW_DLV_ERROR); |
|
353 } |
|
354 |
|
355 res = |
|
356 _dwarf_load_section(dbg, |
|
357 dbg->de_debug_aranges_index, |
|
358 &dbg->de_debug_aranges, error); |
|
359 if (res != DW_DLV_OK) { |
|
360 return res; |
|
361 } |
|
362 |
|
363 arange_ptr = dbg->de_debug_aranges; |
|
364 do { |
|
365 int local_length_size; |
|
366 |
|
367 /*REFERENCED*/ /* not used in this instance of the |
|
368 macro */ |
|
369 int local_extension_size; |
|
370 |
|
371 header_ptr = arange_ptr; |
|
372 |
|
373 |
|
374 /* READ_AREA_LENGTH updates arange_ptr for consumed bytes */ |
|
375 READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned, |
|
376 arange_ptr, local_length_size, |
|
377 local_extension_size); |
|
378 |
|
379 |
|
380 READ_UNALIGNED(dbg, version, Dwarf_Half, |
|
381 arange_ptr, sizeof(Dwarf_Half)); |
|
382 arange_ptr += sizeof(Dwarf_Half); |
|
383 length = length - sizeof(Dwarf_Half); |
|
384 if (version != CURRENT_VERSION_STAMP) { |
|
385 _dwarf_error(dbg, error, DW_DLE_VERSION_STAMP_ERROR); |
|
386 return (DW_DLV_ERROR); |
|
387 } |
|
388 |
|
389 READ_UNALIGNED(dbg, info_offset, Dwarf_Off, |
|
390 arange_ptr, local_length_size); |
|
391 arange_ptr += local_length_size; |
|
392 length = length - local_length_size; |
|
393 if (info_offset >= dbg->de_debug_info_size) { |
|
394 FIX_UP_OFFSET_IRIX_BUG(dbg, info_offset, |
|
395 "arange info offset.b"); |
|
396 if (info_offset >= dbg->de_debug_info_size) { |
|
397 |
|
398 _dwarf_error(dbg, error, DW_DLE_ARANGE_OFFSET_BAD); |
|
399 return (DW_DLV_ERROR); |
|
400 } |
|
401 } |
|
402 |
|
403 address_size = *(Dwarf_Small *) arange_ptr; |
|
404 arange_ptr = arange_ptr + sizeof(Dwarf_Small); |
|
405 length = length - sizeof(Dwarf_Small); |
|
406 |
|
407 segment_size = *(Dwarf_Small *) arange_ptr; |
|
408 arange_ptr = arange_ptr + sizeof(Dwarf_Small); |
|
409 length = length - sizeof(Dwarf_Small); |
|
410 if (segment_size != 0) { |
|
411 _dwarf_error(dbg, error, DW_DLE_SEGMENT_SIZE_BAD); |
|
412 return (DW_DLV_ERROR); |
|
413 } |
|
414 |
|
415 /* Round arange_ptr offset to next multiple of address_size. */ |
|
416 remainder = (Dwarf_Unsigned) (arange_ptr - header_ptr) % |
|
417 (2 * address_size); |
|
418 if (remainder != 0) { |
|
419 arange_ptr = arange_ptr + (2 * address_size) - remainder; |
|
420 length = length - ((2 * address_size) - remainder); |
|
421 } |
|
422 |
|
423 do { |
|
424 arange_start_ptr = arange_ptr; |
|
425 READ_UNALIGNED(dbg, range_address, Dwarf_Addr, |
|
426 arange_ptr, dbg->de_pointer_size); |
|
427 arange_ptr += dbg->de_pointer_size; |
|
428 length = length - dbg->de_pointer_size; |
|
429 |
|
430 READ_UNALIGNED(dbg, range_length, Dwarf_Unsigned, |
|
431 arange_ptr, local_length_size); |
|
432 arange_ptr += local_length_size; |
|
433 length = length - local_length_size; |
|
434 |
|
435 if (range_address != 0 || range_length != 0) { |
|
436 |
|
437 arange = (Dwarf_Arange) |
|
438 _dwarf_get_alloc(dbg, DW_DLA_ARANGE, 1); |
|
439 if (arange == NULL) { |
|
440 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); |
|
441 return (DW_DLV_ERROR); |
|
442 } |
|
443 |
|
444 arange->ar_address = range_address; |
|
445 arange->ar_length = range_length; |
|
446 arange->ar_info_offset = |
|
447 arange_start_ptr - dbg->de_debug_aranges; |
|
448 arange->ar_dbg = dbg; |
|
449 arange_count++; |
|
450 |
|
451 curr_chain = (Dwarf_Chain) |
|
452 _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1); |
|
453 if (curr_chain == NULL) { |
|
454 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); |
|
455 return (DW_DLV_ERROR); |
|
456 } |
|
457 |
|
458 curr_chain->ch_item = arange; |
|
459 if (head_chain == NULL) |
|
460 head_chain = prev_chain = curr_chain; |
|
461 else { |
|
462 prev_chain->ch_next = curr_chain; |
|
463 prev_chain = curr_chain; |
|
464 } |
|
465 } |
|
466 } while (range_address != 0 || range_length != 0); |
|
467 |
|
468 if (length != 0) { |
|
469 _dwarf_error(dbg, error, DW_DLE_ARANGE_LENGTH_BAD); |
|
470 return (DW_DLV_ERROR); |
|
471 } |
|
472 |
|
473 } while (arange_ptr < |
|
474 dbg->de_debug_aranges + dbg->de_debug_aranges_size); |
|
475 |
|
476 if (arange_ptr != |
|
477 dbg->de_debug_aranges + dbg->de_debug_aranges_size) { |
|
478 _dwarf_error(dbg, error, DW_DLE_ARANGE_DECODE_ERROR); |
|
479 return (DW_DLV_ERROR); |
|
480 } |
|
481 |
|
482 arange_addrs = (Dwarf_Addr *) |
|
483 _dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count); |
|
484 if (arange_addrs == NULL) { |
|
485 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); |
|
486 return (DW_DLV_ERROR); |
|
487 } |
|
488 arange_offsets = (Dwarf_Off *) |
|
489 _dwarf_get_alloc(dbg, DW_DLA_ADDR, arange_count); |
|
490 if (arange_offsets == NULL) { |
|
491 _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); |
|
492 return (DW_DLV_ERROR); |
|
493 } |
|
494 |
|
495 curr_chain = head_chain; |
|
496 for (i = 0; i < arange_count; i++) { |
|
497 Dwarf_Arange ar = curr_chain->ch_item; |
|
498 |
|
499 arange_addrs[i] = ar->ar_address; |
|
500 arange_offsets[i] = ar->ar_info_offset; |
|
501 prev_chain = curr_chain; |
|
502 curr_chain = curr_chain->ch_next; |
|
503 dwarf_dealloc(dbg, ar, DW_DLA_ARANGE); |
|
504 dwarf_dealloc(dbg, prev_chain, DW_DLA_CHAIN); |
|
505 } |
|
506 *count = arange_count; |
|
507 *offsets = arange_offsets; |
|
508 *addrs = arange_addrs; |
|
509 return (DW_DLV_OK); |
|
510 } |
|
511 |
|
512 |
|
513 /* |
|
514 This function takes a pointer to a block |
|
515 of Dwarf_Arange's, and a count of the |
|
516 length of the block. It checks if the |
|
517 given address is within the range of an |
|
518 address range in the block. If yes, it |
|
519 returns the appropriate Dwarf_Arange. |
|
520 Otherwise, it returns DW_DLV_ERROR. |
|
521 */ |
|
522 int |
|
523 dwarf_get_arange(Dwarf_Arange * aranges, |
|
524 Dwarf_Unsigned arange_count, |
|
525 Dwarf_Addr address, |
|
526 Dwarf_Arange * returned_arange, Dwarf_Error * error) |
|
527 { |
|
528 Dwarf_Arange curr_arange; |
|
529 Dwarf_Unsigned i; |
|
530 |
|
531 if (aranges == NULL) { |
|
532 _dwarf_error(NULL, error, DW_DLE_ARANGES_NULL); |
|
533 return (DW_DLV_ERROR); |
|
534 } |
|
535 |
|
536 for (i = 0; i < arange_count; i++) { |
|
537 curr_arange = *(aranges + i); |
|
538 if (address >= curr_arange->ar_address && |
|
539 address < |
|
540 curr_arange->ar_address + curr_arange->ar_length) { |
|
541 *returned_arange = curr_arange; |
|
542 return (DW_DLV_OK); |
|
543 } |
|
544 } |
|
545 |
|
546 return (DW_DLV_NO_ENTRY); |
|
547 } |
|
548 |
|
549 |
|
550 /* |
|
551 This function takes an Dwarf_Arange, |
|
552 and returns the offset of the first |
|
553 die in the compilation-unit that the |
|
554 arange belongs to. Returns DW_DLV_ERROR |
|
555 on error. |
|
556 */ |
|
557 int |
|
558 dwarf_get_cu_die_offset(Dwarf_Arange arange, |
|
559 Dwarf_Off * returned_offset, |
|
560 Dwarf_Error * error) |
|
561 { |
|
562 Dwarf_Debug dbg; |
|
563 Dwarf_Off offset; |
|
564 |
|
565 if (arange == NULL) { |
|
566 _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL); |
|
567 return (DW_DLV_ERROR); |
|
568 } |
|
569 |
|
570 |
|
571 dbg = arange->ar_dbg; |
|
572 |
|
573 |
|
574 offset = arange->ar_info_offset; |
|
575 if (!dbg->de_debug_info) { |
|
576 int res = _dwarf_load_debug_info(dbg, error); |
|
577 |
|
578 if (res != DW_DLV_OK) { |
|
579 return res; |
|
580 } |
|
581 } |
|
582 |
|
583 *returned_offset = offset + _dwarf_length_of_cu_header(dbg, offset); |
|
584 return DW_DLV_OK; |
|
585 } |
|
586 |
|
587 /* |
|
588 This function takes an Dwarf_Arange, |
|
589 and returns the offset of the CU header |
|
590 in the compilation-unit that the |
|
591 arange belongs to. Returns DW_DLV_ERROR |
|
592 on error. |
|
593 */ |
|
594 int |
|
595 dwarf_get_arange_cu_header_offset(Dwarf_Arange arange, |
|
596 Dwarf_Off * cu_header_offset_returned, |
|
597 Dwarf_Error * error) |
|
598 { |
|
599 if (arange == NULL) { |
|
600 _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL); |
|
601 return (DW_DLV_ERROR); |
|
602 } |
|
603 |
|
604 *cu_header_offset_returned = arange->ar_info_offset; |
|
605 return DW_DLV_OK; |
|
606 } |
|
607 |
|
608 |
|
609 |
|
610 /* |
|
611 This function takes a Dwarf_Arange, and returns |
|
612 true if it is not NULL. It also stores the start |
|
613 address of the range in *start, the length of the |
|
614 range in *length, and the offset of the first die |
|
615 in the compilation-unit in *cu_die_offset. It |
|
616 returns false on error. |
|
617 */ |
|
618 int |
|
619 dwarf_get_arange_info(Dwarf_Arange arange, |
|
620 Dwarf_Addr * start, |
|
621 Dwarf_Unsigned * length, |
|
622 Dwarf_Off * cu_die_offset, Dwarf_Error * error) |
|
623 { |
|
624 if (arange == NULL) { |
|
625 _dwarf_error(NULL, error, DW_DLE_ARANGE_NULL); |
|
626 return (DW_DLV_ERROR); |
|
627 } |
|
628 |
|
629 if (start != NULL) |
|
630 *start = arange->ar_address; |
|
631 if (length != NULL) |
|
632 *length = arange->ar_length; |
|
633 if (cu_die_offset != NULL) { |
|
634 Dwarf_Debug dbg = arange->ar_dbg; |
|
635 Dwarf_Off offset = arange->ar_info_offset; |
|
636 |
|
637 if (!dbg->de_debug_info) { |
|
638 int res = _dwarf_load_debug_info(dbg, error); |
|
639 |
|
640 if (res != DW_DLV_OK) { |
|
641 return res; |
|
642 } |
|
643 } |
|
644 |
|
645 *cu_die_offset = |
|
646 offset + _dwarf_length_of_cu_header(dbg, offset); |
|
647 } |
|
648 return (DW_DLV_OK); |
|
649 } |