1 /*
2
3 Copyright (C) 2000,2002,2003,2004,2005 Silicon Graphics, Inc. All Rights Reserved.
4 Portions Copyright (C) 2008-2010 Arxan Technologies, Inc. All Rights Reserved.
5 Portions Copyright (C) 2009-2010 David Anderson. All Rights Reserved.
6
7 This program is free software; you can redistribute it and/or modify it
8 under the terms of version 2.1 of the GNU Lesser General Public License
9 as published by the Free Software Foundation.
10
11 This program is distributed in the hope that it would be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
14
15 Further, this software is distributed without any warranty that it is
16 free of the rightful claim of any third person regarding infringement
17 or the like. Any license provided herein, whether implied or
18 otherwise, applies only to this software file. Patent licenses, if
19 any, provided herein do not apply to combinations of this program with
20 other software, or any other product whatsoever.
21
22 You should have received a copy of the GNU Lesser General Public
23 License along with this program; if not, write the Free Software
24 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
25 USA.
26
27 Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
28 Mountain View, CA 94043, or:
29
30 http://www.sgi.com
31
32 For further information regarding this notice, see:
33
34 http://oss.sgi.com/projects/GenInfo/NoticeExplan
35
36 */
37
38 #include "config.h"
39 #include "dwarf_incl.h"
40
41 #include <stdio.h>
42 #include <sys/stat.h>
43 #include <sys/types.h>
44 #include <string.h>
45 #include <stdlib.h>
46
47 #include "dwarf_incl.h"
48 #include "malloc_check.h"
49
50 #define DWARF_DBG_ERROR(dbg,errval,retval) \
51 _dwarf_error(dbg, error, errval); return(retval);
52
53 #define FALSE 0
54 #define TRUE 1
55
56
57
58 /* This static is copied to the dbg on dbg init
59 so that the static need not be referenced at
60 run time, preserving better locality of
61 reference.
62 Value is 0 means do the string check.
63 Value non-zero means do not do the check.
64 */
65 static Dwarf_Small _dwarf_assume_string_bad;
66 static Dwarf_Small _dwarf_apply_relocs = 1;
67
68 /* Call this after calling dwarf_init but before doing anything else.
69 * It applies to all objects, not just the current object.
70 */
71 int
dwarf_set_reloc_application(int apply)72 dwarf_set_reloc_application(int apply)
73 {
74 int oldval = _dwarf_apply_relocs;
75 _dwarf_apply_relocs = apply;
76 return oldval;
77 }
78
79 int
dwarf_set_stringcheck(int newval)80 dwarf_set_stringcheck(int newval)
81 {
82 int oldval = _dwarf_assume_string_bad;
83
84 _dwarf_assume_string_bad = newval;
85 return oldval;
86 }
87
88 /* Unifies the basic duplicate/empty testing and section
89 * data setting to one place. */
90 static int
get_basic_section_data(Dwarf_Debug dbg,struct Dwarf_Section_s * secdata,struct Dwarf_Obj_Access_Section_s * doas,Dwarf_Half section_index,Dwarf_Error * error,int duperr,int emptyerr)91 get_basic_section_data(Dwarf_Debug dbg,
92 struct Dwarf_Section_s *secdata,
93 struct Dwarf_Obj_Access_Section_s *doas,
94 Dwarf_Half section_index,
95 Dwarf_Error* error,
96 int duperr, int emptyerr )
97 {
98 if (secdata->dss_index != 0) {
99 DWARF_DBG_ERROR(dbg, duperr, DW_DLV_ERROR);
100 }
101 if (doas->size == 0) {
102 if (emptyerr == 0 ) {
103 /* Allow empty section. */
104 return DW_DLV_OK;
105 }
106 /* Know no reason to allow section */
107 DWARF_DBG_ERROR(dbg, emptyerr, DW_DLV_ERROR);
108 }
109 secdata->dss_index = section_index;
110 secdata->dss_size = doas->size;
111 secdata->dss_addr = doas->addr;
112 secdata->dss_link = doas->link;
113 return DW_DLV_OK;
114 }
115
116
117 static void
add_rela_data(struct Dwarf_Section_s * secdata,struct Dwarf_Obj_Access_Section_s * doas,Dwarf_Half section_index)118 add_rela_data( struct Dwarf_Section_s *secdata,
119 struct Dwarf_Obj_Access_Section_s *doas,
120 Dwarf_Half section_index)
121 {
122 secdata->dss_reloc_index = section_index;
123 secdata->dss_reloc_size = doas->size;
124 secdata->dss_reloc_addr = doas->addr;
125 secdata->dss_reloc_symtab = doas->link;
126 secdata->dss_reloc_link = doas->link;
127 }
128
129 /*
130 Given an Elf ptr, set up dbg with pointers
131 to all the Dwarf data sections.
132 Return NULL on error.
133
134 This function is also responsible for determining
135 whether the given object contains Dwarf information
136 or not. The test currently used is that it contains
137 either a .debug_info or a .debug_frame section. If
138 not, it returns DW_DLV_NO_ENTRY causing dwarf_init() also to
139 return DW_DLV_NO_ENTRY. Earlier, we had thought of using only
140 the presence/absence of .debug_info to test, but we
141 added .debug_frame since there could be stripped objects
142 that have only a .debug_frame section for exception
143 processing.
144 DW_DLV_NO_ENTRY or DW_DLV_OK or DW_DLV_ERROR
145 */
146 static int
_dwarf_setup(Dwarf_Debug dbg,Dwarf_Error * error)147 _dwarf_setup(Dwarf_Debug dbg, Dwarf_Error * error)
148 {
149 const char *scn_name = 0;
150 int foundDwarf = 0;
151 struct Dwarf_Obj_Access_Interface_s * obj = 0;
152
153 Dwarf_Endianness endianness;
154
155 Dwarf_Unsigned section_size = 0;
156 Dwarf_Unsigned section_count = 0;
157 Dwarf_Half section_index = 0;
158 Dwarf_Addr section_addr = 0;
159
160 foundDwarf = FALSE;
161
162 dbg->de_assume_string_in_bounds = _dwarf_assume_string_bad;
163
164 dbg->de_same_endian = 1;
165 dbg->de_copy_word = memcpy;
166 obj = dbg->de_obj_file;
167 endianness = obj->methods->get_byte_order(obj->object);
168 #ifdef WORDS_BIGENDIAN
169 dbg->de_big_endian_object = 1;
170 if (endianness == DW_OBJECT_LSB ) {
171 dbg->de_same_endian = 0;
172 dbg->de_big_endian_object = 0;
173 dbg->de_copy_word = _dwarf_memcpy_swap_bytes;
174 }
175 #else /* little endian */
176 dbg->de_big_endian_object = 0;
177 if (endianness == DW_OBJECT_MSB ) {
178 dbg->de_same_endian = 0;
179 dbg->de_big_endian_object = 1;
180 dbg->de_copy_word = _dwarf_memcpy_swap_bytes;
181 }
182 #endif /* !WORDS_BIGENDIAN */
183
184
185 /* The following de_length_size is Not Too Significant. Only used
186 one calculation, and an approximate one at that. */
187 dbg->de_length_size = obj->methods->get_length_size(obj->object);
188 dbg->de_pointer_size = obj->methods->get_pointer_size(obj->object);
189
190 section_count = obj->methods->get_section_count(obj->object);
191
192 /* We can skip index 0 when considering ELF files, but not other
193 object types. */
194 for (section_index = 0; section_index < section_count;
195 ++section_index) {
196
197 struct Dwarf_Obj_Access_Section_s doas;
198 int res = DW_DLV_ERROR;
199 int err;
200
201 res = obj->methods->get_section_info(obj->object,
202 section_index,
203 &doas, &err);
204 if(res == DW_DLV_ERROR){
205 DWARF_DBG_ERROR(dbg, err, DW_DLV_ERROR);
206 }
207
208 section_addr = doas.addr;
209 section_size = doas.size;
210 scn_name = doas.name;
211
212 if (strncmp(scn_name, ".debug_", 7)
213 && strcmp(scn_name, ".eh_frame")
214 && strcmp(scn_name, ".symtab")
215 && strcmp(scn_name, ".strtab")
216 && strncmp(scn_name, ".rela.",6)) {
217 continue;
218 }
219 else if (strcmp(scn_name, ".debug_info") == 0) {
220 res = get_basic_section_data(dbg,&dbg->de_debug_info, &doas,
221 section_index,error,
222 DW_DLE_DEBUG_INFO_DUPLICATE,DW_DLE_DEBUG_INFO_NULL);
223 if(res != DW_DLV_OK) {
224 return res;
225 }
226 foundDwarf = TRUE;
227 }
228 else if (strcmp(scn_name, ".debug_abbrev") == 0) {
229 res = get_basic_section_data(dbg,&dbg->de_debug_abbrev, &doas,
230 section_index,error,
231 DW_DLE_DEBUG_ABBREV_DUPLICATE,DW_DLE_DEBUG_ABBREV_NULL);
232 if(res != DW_DLV_OK) {
233 return res;
234 }
235 }
236 else if (strcmp(scn_name, ".debug_aranges") == 0) {
237 res = get_basic_section_data(dbg,&dbg->de_debug_aranges, &doas,
238 section_index,error,
239 DW_DLE_DEBUG_ARANGES_DUPLICATE,0);
240 if(res != DW_DLV_OK) {
241 return res;
242 }
243 }
244
245 else if (strcmp(scn_name, ".debug_line") == 0) {
246 res = get_basic_section_data(dbg,&dbg->de_debug_line, &doas,
247 section_index,error,
248 DW_DLE_DEBUG_LINE_DUPLICATE,0);
249 if(res != DW_DLV_OK) {
250 return res;
251 }
252 }
253 else if (strcmp(scn_name, ".debug_frame") == 0) {
254 res = get_basic_section_data(dbg,&dbg->de_debug_frame, &doas,
255 section_index,error,
256 DW_DLE_DEBUG_FRAME_DUPLICATE,0);
257 if(res != DW_DLV_OK) {
258 return res;
259 }
260 foundDwarf = TRUE;
261 } else if (strcmp(scn_name, ".eh_frame") == 0) {
262 /* gnu egcs-1.1.2 data */
263 res = get_basic_section_data(dbg,&dbg->de_debug_frame_eh_gnu, &doas,
264 section_index,error,
265 DW_DLE_DEBUG_FRAME_DUPLICATE,0);
266 if(res != DW_DLV_OK) {
267 return res;
268 }
269 foundDwarf = TRUE;
270 }
271 else if (strcmp(scn_name, ".debug_loc") == 0) {
272 res = get_basic_section_data(dbg,&dbg->de_debug_loc, &doas,
273 section_index,error,
274 DW_DLE_DEBUG_LOC_DUPLICATE,0);
275 if(res != DW_DLV_OK) {
276 return res;
277 }
278 }
279 else if (strcmp(scn_name, ".debug_pubnames") == 0) {
280 res = get_basic_section_data(dbg,&dbg->de_debug_pubnames, &doas,
281 section_index,error,
282 DW_DLE_DEBUG_PUBNAMES_DUPLICATE,0);
283 if(res != DW_DLV_OK) {
284 return res;
285 }
286 }
287
288 else if (strcmp(scn_name, ".debug_str") == 0) {
289 res = get_basic_section_data(dbg,&dbg->de_debug_str, &doas,
290 section_index,error,
291 DW_DLE_DEBUG_STR_DUPLICATE,0);
292 if(res != DW_DLV_OK) {
293 return res;
294 }
295 }
296 else if (strcmp(scn_name, ".debug_funcnames") == 0) {
297 /* SGI IRIX-only. */
298 res = get_basic_section_data(dbg,&dbg->de_debug_funcnames, &doas,
299 section_index,error,
300 DW_DLE_DEBUG_FUNCNAMES_DUPLICATE,0);
301 if(res != DW_DLV_OK) {
302 return res;
303 }
304 }
305 else if (strcmp(scn_name, ".debug_typenames") == 0) {
306 /* SGI IRIX-only, created years before DWARF3. Content
307 essentially identical to .debug_pubtypes. */
308 res = get_basic_section_data(dbg,&dbg->de_debug_typenames, &doas,
309 section_index,error,
310 DW_DLE_DEBUG_TYPENAMES_DUPLICATE,0);
311 if(res != DW_DLV_OK) {
312 return res;
313 }
314 } else if (strcmp(scn_name, ".debug_pubtypes") == 0) {
315 /* Section new in DWARF3. */
316 res = get_basic_section_data(dbg,&dbg->de_debug_pubtypes, &doas,
317 section_index,error,
318 DW_DLE_DEBUG_PUBTYPES_DUPLICATE,0);
319 if(res != DW_DLV_OK) {
320 return res;
321 }
322 }
323 else if (strcmp(scn_name, ".debug_varnames") == 0) {
324 /* SGI IRIX-only. */
325 res = get_basic_section_data(dbg,&dbg->de_debug_varnames, &doas,
326 section_index,error,
327 DW_DLE_DEBUG_VARNAMES_DUPLICATE,0);
328 if(res != DW_DLV_OK) {
329 return res;
330 }
331 }
332 else if (strcmp(scn_name, ".debug_weaknames") == 0) {
333 /* SGI IRIX-only. */
334 res = get_basic_section_data(dbg,&dbg->de_debug_weaknames, &doas,
335 section_index,error,
336 DW_DLE_DEBUG_WEAKNAMES_DUPLICATE,0);
337 if(res != DW_DLV_OK) {
338 return res;
339 }
340 } else if (strcmp(scn_name, ".debug_macinfo") == 0) {
341 res = get_basic_section_data(dbg,&dbg->de_debug_macinfo, &doas,
342 section_index,error,
343 DW_DLE_DEBUG_MACINFO_DUPLICATE,0);
344 if(res != DW_DLV_OK) {
345 return res;
346 }
347 }
348 else if (strcmp(scn_name, ".debug_ranges") == 0) {
349 res = get_basic_section_data(dbg,&dbg->de_debug_ranges, &doas,
350 section_index,error,
351 DW_DLE_DEBUG_RANGES_DUPLICATE,0);
352 if(res != DW_DLV_OK) {
353 return res;
354 }
355 foundDwarf = TRUE;
356 }
357 else if (strcmp(scn_name, ".symtab") == 0) {
358 res = get_basic_section_data(dbg,&dbg->de_elf_symtab, &doas,
359 section_index,error,
360 DW_DLE_DEBUG_SYMTAB_ERR,0);
361 if(res != DW_DLV_OK) {
362 return res;
363 }
364 }
365 else if (strcmp(scn_name, ".strtab") == 0) {
366 res = get_basic_section_data(dbg,&dbg->de_elf_strtab, &doas,
367 section_index,error,
368 DW_DLE_DEBUG_STRTAB_ERR,0);
369 if(res != DW_DLV_OK) {
370 return res;
371 }
372 }
373 else if (strncmp(scn_name, ".rela.debug_",12) == 0) {
374 const char *rcn_name = scn_name + 5;
375 if (strcmp(rcn_name, ".debug_info") == 0) {
376 add_rela_data(&dbg->de_debug_info,&doas,section_index);
377 } else if (strcmp(rcn_name, ".debug_abbrev") == 0) {
378 add_rela_data(&dbg->de_debug_abbrev,&doas,section_index);
379 } else if (strcmp(rcn_name, ".debug_aranges") == 0) {
380 add_rela_data(&dbg->de_debug_aranges,&doas,section_index);
381 } else if (strcmp(rcn_name, ".debug_line") == 0) {
382 add_rela_data(&dbg->de_debug_line,&doas,section_index);
383 } else if (strcmp(rcn_name, ".debug_frame") == 0) {
384 add_rela_data(&dbg->de_debug_frame,&doas,section_index);
385 } else if (strcmp(rcn_name, ".eh_frame") == 0) {
386 add_rela_data(&dbg->de_debug_frame_eh_gnu,&doas,section_index);
387 } else if (strcmp(rcn_name, ".debug_loc") == 0) {
388 add_rela_data(&dbg->de_debug_loc,&doas,section_index);
389 } else if (strcmp(rcn_name, ".debug_pubnames") == 0) {
390 add_rela_data(&dbg->de_debug_pubnames,&doas,section_index);
391 } else if (strcmp(rcn_name, ".debug_str") == 0) {
392 add_rela_data(&dbg->de_debug_str,&doas,section_index);
393 } else if (strcmp(rcn_name, ".debug_funcnames") == 0) {
394 add_rela_data(&dbg->de_debug_funcnames,&doas,section_index);
395 } else if (strcmp(rcn_name, ".debug_typenames") == 0) {
396 add_rela_data(&dbg->de_debug_typenames,&doas,section_index);
397 } else if (strcmp(rcn_name, ".debug_pubtypes") == 0) {
398 add_rela_data(&dbg->de_debug_pubtypes,&doas,section_index);
399 } else if (strcmp(rcn_name, ".debug_varnames") == 0) {
400 add_rela_data(&dbg->de_debug_varnames,&doas,section_index);
401 } else if (strcmp(rcn_name, ".debug_weaknames") == 0) {
402 add_rela_data(&dbg->de_debug_weaknames,&doas,section_index);
403 } else if (strcmp(rcn_name, ".debug_macinfo") == 0) {
404 add_rela_data(&dbg->de_debug_macinfo,&doas,section_index);
405 }
406 }
407 }
408 if (foundDwarf) {
409 return DW_DLV_OK;
410 }
411 return DW_DLV_NO_ENTRY;
412 }
413
414
415 /*
416 Use a Dwarf_Obj_Access_Interface to kick things off. All other
417 init routines eventually use this one.
418 The returned Dwarf_Debug contains a copy of *obj
419 the callers copy of *obj may be freed whenever the caller
420 wishes.
421 */
422 int
dwarf_object_init(Dwarf_Obj_Access_Interface * obj,Dwarf_Handler errhand,Dwarf_Ptr errarg,Dwarf_Debug * ret_dbg,Dwarf_Error * error)423 dwarf_object_init(Dwarf_Obj_Access_Interface* obj, Dwarf_Handler errhand,
424 Dwarf_Ptr errarg, Dwarf_Debug* ret_dbg,
425 Dwarf_Error* error)
426 {
427 Dwarf_Debug dbg = 0;
428 int setup_result = DW_DLV_OK;
429
430 dbg = _dwarf_get_debug();
431 if (dbg == NULL) {
432 DWARF_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, DW_DLV_ERROR);
433 }
434 dbg->de_errhand = errhand;
435 dbg->de_errarg = errarg;
436 dbg->de_frame_rule_initial_value = DW_FRAME_REG_INITIAL_VALUE;
437 dbg->de_frame_reg_rules_entry_count = DW_FRAME_LAST_REG_NUM;
438 #ifdef HAVE_OLD_FRAME_CFA_COL
439 /* DW_FRAME_CFA_COL is really only suitable for old libdwarf frame
440 interfaces and its value of 0 there is only usable where
441 (as in MIPS) register 0 has no value other than 0 so
442 we can use the frame table column 0 for the CFA value
443 (and rely on client software to know when 'register 0'
444 is the cfa and when to just use a value 0 for register 0).
445 */
446 dbg->de_frame_cfa_col_number = DW_FRAME_CFA_COL;
447 #else
448 dbg->de_frame_cfa_col_number = DW_FRAME_CFA_COL3;
449 #endif
450 dbg->de_frame_same_value_number = DW_FRAME_SAME_VAL;
451 dbg->de_frame_undefined_value_number = DW_FRAME_UNDEFINED_VAL;
452
453 dbg->de_obj_file = obj;
454
455 setup_result = _dwarf_setup(dbg, error);
456 if (setup_result != DW_DLV_OK) {
457 /* The status we want to return here is of _dwarf_setup,
458 not of the _dwarf_free_all_of_one_debug(dbg) call.
459 So use a local status variable for the free. */
460 int freeresult = _dwarf_free_all_of_one_debug(dbg);
461 if (freeresult == DW_DLV_ERROR) {
462 DWARF_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, DW_DLV_ERROR);
463 }
464 dwarf_malloc_check_complete("After Final free");
465 return setup_result;
466 }
467
468 dwarf_harmless_init(&dbg->de_harmless_errors,
469 DW_HARMLESS_ERROR_CIRCULAR_LIST_DEFAULT_SIZE);
470
471 /* This call cannot fail: allocates nothing, releases nothing */
472 _dwarf_setup_debug(dbg);
473
474
475 *ret_dbg = dbg;
476 return DW_DLV_OK;
477 }
478
479
480 /*
481 A finish routine that is completely unaware of ELF.
482
483 Frees all memory that was not previously freed by
484 dwarf_dealloc.
485 Aside frmo certain categories.
486 */
487 int
dwarf_object_finish(Dwarf_Debug dbg,Dwarf_Error * error)488 dwarf_object_finish(Dwarf_Debug dbg, Dwarf_Error * error)
489 {
490 int res = DW_DLV_OK;
491
492 res = _dwarf_free_all_of_one_debug(dbg);
493 if (res == DW_DLV_ERROR) {
494 DWARF_DBG_ERROR(dbg, DW_DLE_DBG_ALLOC, DW_DLV_ERROR);
495 }
496 dwarf_malloc_check_complete("After Final free");
497
498 return res;
499 }
500
501
502 /*
503 Load the ELF section with the specified index and set the
504 pointer pointed to by section_data to the memory where it
505 was loaded.
506 */
507 int
_dwarf_load_section(Dwarf_Debug dbg,struct Dwarf_Section_s * section,Dwarf_Error * error)508 _dwarf_load_section(Dwarf_Debug dbg,
509 struct Dwarf_Section_s *section,
510 Dwarf_Error * error)
511 {
512 int res = DW_DLV_ERROR;
513 int err = 0;
514 struct Dwarf_Obj_Access_Interface_s *o = 0;
515
516 /* check to see if the section is already loaded */
517 if (section->dss_data != NULL) {
518 return DW_DLV_OK;
519 }
520 o = dbg->de_obj_file;
521 res = o->methods->load_section(
522 o->object, section->dss_index,
523 §ion->dss_data, &err);
524 if(res == DW_DLV_ERROR){
525 DWARF_DBG_ERROR(dbg, err, DW_DLV_ERROR);
526 }
527 if(_dwarf_apply_relocs == 0) {
528 return res;
529 }
530 if(section->dss_reloc_size == 0) {
531 return res;
532 }
533 if(!o->methods->relocate_a_section) {
534 return res;
535 }
536 /*apply relocations */
537 res = o->methods->relocate_a_section( o->object, section->dss_index,
538 dbg, &err);
539 if(res == DW_DLV_ERROR) {
540 DWARF_DBG_ERROR(dbg, err, DW_DLV_ERROR);
541 }
542 return res;
543 }
544
545 /* This is a hack so clients can verify offsets.
546 Added April 2005 so that debugger can detect broken offsets
547 (which happened in an IRIX -64 executable larger than 2GB
548 using MIPSpro 7.3.1.3 compilers. A couple .debug_pubnames
549 offsets were wrong.).
550 */
551 int
dwarf_get_section_max_offsets(Dwarf_Debug dbg,Dwarf_Unsigned * debug_info_size,Dwarf_Unsigned * debug_abbrev_size,Dwarf_Unsigned * debug_line_size,Dwarf_Unsigned * debug_loc_size,Dwarf_Unsigned * debug_aranges_size,Dwarf_Unsigned * debug_macinfo_size,Dwarf_Unsigned * debug_pubnames_size,Dwarf_Unsigned * debug_str_size,Dwarf_Unsigned * debug_frame_size,Dwarf_Unsigned * debug_ranges_size,Dwarf_Unsigned * debug_typenames_size)552 dwarf_get_section_max_offsets(Dwarf_Debug dbg,
553 Dwarf_Unsigned * debug_info_size,
554 Dwarf_Unsigned * debug_abbrev_size,
555 Dwarf_Unsigned * debug_line_size,
556 Dwarf_Unsigned * debug_loc_size,
557 Dwarf_Unsigned * debug_aranges_size,
558 Dwarf_Unsigned * debug_macinfo_size,
559 Dwarf_Unsigned * debug_pubnames_size,
560 Dwarf_Unsigned * debug_str_size,
561 Dwarf_Unsigned * debug_frame_size,
562 Dwarf_Unsigned * debug_ranges_size,
563 Dwarf_Unsigned * debug_typenames_size)
564 {
565 *debug_info_size = dbg->de_debug_info.dss_size;
566 *debug_abbrev_size = dbg->de_debug_abbrev.dss_size;
567 *debug_line_size = dbg->de_debug_line.dss_size;
568 *debug_loc_size = dbg->de_debug_loc.dss_size;
569 *debug_aranges_size = dbg->de_debug_aranges.dss_size;
570 *debug_macinfo_size = dbg->de_debug_macinfo.dss_size;
571 *debug_pubnames_size = dbg->de_debug_pubnames.dss_size;
572 *debug_str_size = dbg->de_debug_str.dss_size;
573 *debug_frame_size = dbg->de_debug_frame.dss_size;
574 *debug_ranges_size = dbg->de_debug_ranges.dss_size;
575 *debug_typenames_size = dbg->de_debug_typenames.dss_size;
576 return DW_DLV_OK;
577 }
578