tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_addr_finder.c
changeset 34 92d87f2e53c2
equal deleted inserted replaced
33:1af5c1be89f8 34:92d87f2e53c2
       
     1 /*
       
     2 
       
     3   Copyright (C) 2000,2002,2004 Silicon Graphics, Inc.  All Rights Reserved.
       
     4 
       
     5   This program is free software; you can redistribute it and/or modify it
       
     6   under the terms of version 2.1 of the GNU Lesser General Public License 
       
     7   as published by the Free Software Foundation.
       
     8 
       
     9   This program is distributed in the hope that it would be useful, but
       
    10   WITHOUT ANY WARRANTY; without even the implied warranty of
       
    11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
       
    12 
       
    13   Further, this software is distributed without any warranty that it is
       
    14   free of the rightful claim of any third person regarding infringement 
       
    15   or the like.  Any license provided herein, whether implied or 
       
    16   otherwise, applies only to this software file.  Patent licenses, if
       
    17   any, provided herein do not apply to combinations of this program with 
       
    18   other software, or any other product whatsoever.  
       
    19 
       
    20   You should have received a copy of the GNU Lesser General Public 
       
    21   License along with this program; if not, write the Free Software 
       
    22   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
       
    23   USA.
       
    24 
       
    25   Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
       
    26   Mountain View, CA 94043, or:
       
    27 
       
    28   http://www.sgi.com
       
    29 
       
    30   For further information regarding this notice, see:
       
    31 
       
    32   http://oss.sgi.com/projects/GenInfo/NoticeExplan
       
    33 
       
    34 */
       
    35 /* This code used by SGI-IRIX rqs processing, not needed by
       
    36    any other system or application.
       
    37 */
       
    38 
       
    39 #include "config.h"
       
    40 #include "libdwarfdefs.h"
       
    41 #ifdef HAVE_ELF_H
       
    42 #include <elf.h>
       
    43 #endif
       
    44 #include <dwarf.h>
       
    45 #include <libdwarf.h>
       
    46 #include "dwarf_base_types.h"
       
    47 #include "dwarf_alloc.h"
       
    48 #include "dwarf_opaque.h"
       
    49 #include "dwarf_arange.h"
       
    50 #include "dwarf_line.h"
       
    51 #include "dwarf_frame.h"
       
    52 #include <cmplrs/dwarf_addr_finder.h>
       
    53 #include "dwarf_error.h"
       
    54 
       
    55 typedef unsigned long long ull;
       
    56 
       
    57 static int do_this_die_and_dealloc(Dwarf_Debug dbg, Dwarf_Die die,
       
    58 				   int *errval);
       
    59 static int
       
    60   handle_debug_info(Dwarf_Debug dbg, int *errval);
       
    61 static int
       
    62   handle_debug_frame(Dwarf_Debug dbg, Dwarf_addr_callback_func cb_func, int *errval);
       
    63 static int
       
    64   handle_debug_aranges(Dwarf_Debug dbg, Dwarf_addr_callback_func cb_func, int *errval);
       
    65 static int
       
    66   handle_debug_line(Dwarf_Debug dbg, Dwarf_Die cu_die, Dwarf_addr_callback_func cb_func, int *errval);
       
    67 static int
       
    68   handle_debug_loc(void);
       
    69 
       
    70 
       
    71 static Dwarf_addr_callback_func send_addr_note;
       
    72 
       
    73 int
       
    74 _dwarf_addr_finder(dwarf_elf_handle elf_file_ptr,
       
    75 		   Dwarf_addr_callback_func cb_func, int *dwerr)
       
    76 {
       
    77 
       
    78     Dwarf_Error err = 0;
       
    79     Dwarf_Debug dbg = 0;
       
    80     int res = 0;
       
    81     int errval = 0;
       
    82     int sections_found = 0;
       
    83 
       
    84     res = dwarf_elf_init(elf_file_ptr, DW_DLC_READ, /* errhand */ 0,
       
    85 			 /* errarg */ 0, &dbg, &err);
       
    86     if (res == DW_DLV_ERROR) {
       
    87 	int errv = (int) dwarf_errno(err);
       
    88 
       
    89 	return errv;
       
    90     }
       
    91     if (res == DW_DLV_NO_ENTRY) {
       
    92 	return res;
       
    93     }
       
    94 
       
    95     send_addr_note = cb_func;
       
    96 
       
    97     res = handle_debug_info(dbg, &errval);
       
    98     switch (res) {
       
    99     case DW_DLV_OK:
       
   100 	++sections_found;
       
   101 	break;
       
   102     case DW_DLV_NO_ENTRY:
       
   103 
       
   104 	break;
       
   105     default:
       
   106     case DW_DLV_ERROR:
       
   107 	dwarf_finish(dbg, &err);
       
   108 	*dwerr = errval;
       
   109 	return res;
       
   110     }
       
   111 
       
   112     res = handle_debug_aranges(dbg, cb_func, &errval);
       
   113     switch (res) {
       
   114     case DW_DLV_OK:
       
   115 	++sections_found;
       
   116 	break;
       
   117     case DW_DLV_NO_ENTRY:
       
   118 	break;
       
   119     default:
       
   120     case DW_DLV_ERROR:
       
   121 	dwarf_finish(dbg, &err);
       
   122 	*dwerr = errval;
       
   123 	return res;
       
   124     }
       
   125     res = handle_debug_frame(dbg, cb_func, &errval);
       
   126     switch (res) {
       
   127     case DW_DLV_OK:
       
   128 	++sections_found;
       
   129 	break;
       
   130     case DW_DLV_NO_ENTRY:
       
   131 	break;
       
   132     default:
       
   133     case DW_DLV_ERROR:
       
   134 	dwarf_finish(dbg, &err);
       
   135 	*dwerr = errval;
       
   136 	return res;
       
   137     }
       
   138 
       
   139     res = handle_debug_loc();	/* does nothing */
       
   140     switch (res) {
       
   141     case DW_DLV_OK:
       
   142 	++sections_found;
       
   143 	break;
       
   144     case DW_DLV_NO_ENTRY:
       
   145 	break;
       
   146     default:
       
   147     case DW_DLV_ERROR:
       
   148 	/* IMPOSSIBLE : handle_debug_loc cannot return this */
       
   149 	dwarf_finish(dbg, &err);
       
   150 	*dwerr = errval;
       
   151 	return res;
       
   152     }
       
   153 
       
   154 
       
   155 
       
   156     *dwerr = 0;
       
   157     res = dwarf_finish(dbg, &err);
       
   158     if (res == DW_DLV_ERROR) {
       
   159 	*dwerr = (int) dwarf_errno(err);
       
   160 	return DW_DLV_ERROR;
       
   161     }
       
   162     if (sections_found == 0) {
       
   163 	return DW_DLV_NO_ENTRY;
       
   164     }
       
   165     return DW_DLV_OK;
       
   166 
       
   167 }
       
   168 
       
   169 /*
       
   170 	Return DW_DLV_OK, ERROR, or NO_ENTRY.
       
   171 */
       
   172 static int
       
   173 handle_debug_info(Dwarf_Debug dbg, int *errval)
       
   174 {
       
   175     Dwarf_Unsigned nxtoff = 1;
       
   176     Dwarf_Unsigned hdr_length;
       
   177     Dwarf_Half version_stamp;
       
   178     Dwarf_Unsigned abbrev_offset;
       
   179     Dwarf_Half addr_size;
       
   180     Dwarf_Error err;
       
   181     int terminate_now = 0;
       
   182     int res = 0;
       
   183     Dwarf_Die sibdie;
       
   184     int sibres;
       
   185     int nres = DW_DLV_OK;
       
   186 
       
   187 
       
   188     for (nres = dwarf_next_cu_header(dbg, &hdr_length, &version_stamp,
       
   189 				     &abbrev_offset,
       
   190 				     &addr_size, &nxtoff, &err);
       
   191 	 terminate_now == 0 && nres == DW_DLV_OK;
       
   192 	 nres = dwarf_next_cu_header(dbg, &hdr_length, &version_stamp,
       
   193 				     &abbrev_offset,
       
   194 				     &addr_size, &nxtoff, &err)
       
   195 	) {
       
   196 
       
   197 	Dwarf_Die curdie = 0;
       
   198 
       
   199 	/* try to get the compilation unit die */
       
   200 	sibres = dwarf_siblingof(dbg, curdie, &sibdie, &err);
       
   201 	if (sibres == DW_DLV_OK) {
       
   202 	    res = do_this_die_and_dealloc(dbg, sibdie, errval);
       
   203 	    switch (res) {
       
   204 	    case DW_DLV_OK:
       
   205 		break;
       
   206 	    case DW_DLV_NO_ENTRY:
       
   207 		break;
       
   208 	    default:
       
   209 	    case DW_DLV_ERROR:
       
   210 		return DW_DLV_ERROR;
       
   211 	    }
       
   212 	} else if (sibres == DW_DLV_ERROR) {
       
   213 	    *errval = (int) dwarf_errno(err);
       
   214 	    return DW_DLV_ERROR;
       
   215 	} else {
       
   216 	    /* NO ENTRY! */
       
   217 	    /* impossible? */
       
   218 	}
       
   219 
       
   220     }
       
   221     if (nres == DW_DLV_ERROR) {
       
   222 	int localerr = (int) dwarf_errno(err);
       
   223 
       
   224 	*errval = localerr;
       
   225 	return DW_DLV_ERROR;
       
   226     }
       
   227     return DW_DLV_OK;
       
   228 }
       
   229 
       
   230 static int
       
   231   might_have_addr[] = {
       
   232     DW_AT_high_pc,
       
   233     DW_AT_low_pc,
       
   234 };
       
   235 static int
       
   236   might_have_locdesc[] = {
       
   237     DW_AT_segment,
       
   238     DW_AT_return_addr,
       
   239     DW_AT_frame_base,
       
   240     DW_AT_static_link,
       
   241     DW_AT_data_member_location,
       
   242     DW_AT_string_length,
       
   243     DW_AT_location,
       
   244     DW_AT_use_location,
       
   245     DW_AT_vtable_elem_location,
       
   246 };
       
   247 
       
   248 /*
       
   249 	Return DW_DLV_OK if handling this went ok.
       
   250 */
       
   251 static int
       
   252 handle_attr_addr(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Half attrnum,
       
   253 		 Dwarf_Error * perr)
       
   254 {
       
   255     int res = DW_DLV_OK;
       
   256     Dwarf_Off offset;
       
   257     Dwarf_Addr addr;
       
   258     Dwarf_Half form;
       
   259     int ares;
       
   260 
       
   261     Dwarf_Attribute attr;
       
   262 
       
   263     ares = dwarf_attr(die, attrnum, &attr, perr);
       
   264     if (ares == DW_DLV_OK) {
       
   265 	int formres = dwarf_whatform(attr, &form, perr);
       
   266 
       
   267 	switch (formres) {
       
   268 	case DW_DLV_OK:
       
   269 	    break;
       
   270 	case DW_DLV_ERROR:
       
   271 	case DW_DLV_NO_ENTRY:	/* impossible. */
       
   272 	    return formres;
       
   273 
       
   274 	}
       
   275 
       
   276 	switch (form) {
       
   277 	case DW_FORM_ref_addr:
       
   278 	case DW_FORM_addr:
       
   279 	    res = dwarf_attr_offset(die, attr, &offset, perr);
       
   280 	    if (res == DW_DLV_OK) {
       
   281 		ares = dwarf_formaddr(attr, &addr, perr);
       
   282 		if (ares == DW_DLV_OK) {
       
   283 		    send_addr_note(DW_SECTION_INFO, offset, addr);
       
   284 		} else if (ares == DW_DLV_ERROR) {
       
   285 		    return ares;
       
   286 		}		/* no entry: ok. */
       
   287 	    } else {
       
   288 		res = DW_DLV_ERROR;	/* NO_ENTRY is impossible. */
       
   289 	    }
       
   290 	    break;
       
   291 
       
   292 	default:
       
   293 	    /* surprising! An error? */
       
   294 
       
   295 	    ;			/* do nothing */
       
   296 	}
       
   297 	dwarf_dealloc(dbg, attr, DW_DLA_ATTR);
       
   298 
       
   299     } else {
       
   300 	res = ares;
       
   301     }
       
   302     return res;
       
   303 }
       
   304 
       
   305 /*
       
   306 	Return DW_DLV_OK if handling this went ok.
       
   307 */
       
   308 static int
       
   309 handle_attr_locdesc(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Half attrnum,
       
   310 		    Dwarf_Error * perr)
       
   311 {
       
   312     int retval = DW_DLV_OK;
       
   313     Dwarf_Attribute attr;
       
   314     Dwarf_Locdesc *llbuf;
       
   315     Dwarf_Signed i;
       
   316     Dwarf_Off offset;
       
   317     Dwarf_Loc *locp;
       
   318     unsigned int entindx;
       
   319     int res;
       
   320     int ares;
       
   321 
       
   322 
       
   323     ares = dwarf_attr(die, attrnum, &attr, perr);
       
   324     if (ares == DW_DLV_OK) {
       
   325 	Dwarf_Half form;
       
   326 	int fres = dwarf_whatform(attr, &form, perr);
       
   327 
       
   328 	if (fres == DW_DLV_OK) {
       
   329 	    switch (form) {
       
   330 	    case DW_FORM_block1:
       
   331 	    case DW_FORM_block2:
       
   332 	    case DW_FORM_block4:
       
   333 		/* must be location description */
       
   334 		res = dwarf_attr_offset(die, attr, &offset, perr);
       
   335 		llbuf = 0;
       
   336 		if (res == DW_DLV_OK) {
       
   337 		    Dwarf_Signed count;
       
   338 		    int lres =
       
   339 			dwarf_loclist(attr, &llbuf, &count, perr);
       
   340 		    if (lres != DW_DLV_OK) {
       
   341 			return lres;
       
   342 		    }
       
   343 		    if (count != 1) {
       
   344 			/* this cannot happen! */
       
   345 			/* perr? */
       
   346 			_dwarf_error(dbg, perr,
       
   347 				     DW_DLE_LOCDESC_COUNT_WRONG);
       
   348 			retval = DW_DLV_ERROR;
       
   349 			return retval;
       
   350 		    }
       
   351 		    for (i = 0; i < count; ++i) {
       
   352 			unsigned int ents = llbuf[i].ld_cents;
       
   353 
       
   354 			locp = llbuf[i].ld_s;
       
   355 			for (entindx = 0; entindx < ents; entindx++) {
       
   356 			    Dwarf_Loc *llocp;
       
   357 
       
   358 			    llocp = locp + entindx;
       
   359 			    if (llocp->lr_atom == DW_OP_addr) {
       
   360 				send_addr_note(DW_SECTION_INFO, offset +
       
   361 					       llocp->lr_offset + 1
       
   362 					       /* The offset is the
       
   363 					          offset of the atom,
       
   364 					          ** and we know the
       
   365 					          addr is 1 past it. */
       
   366 					       , llocp->lr_number);
       
   367 			    }
       
   368 			}
       
   369 		    }
       
   370 
       
   371 
       
   372 		    if (count > 0) {
       
   373 			for (i = 0; i < count; ++i) {
       
   374 			    dwarf_dealloc(dbg, llbuf[i].ld_s,
       
   375 					  DW_DLA_LOC_BLOCK);
       
   376 			}
       
   377 			dwarf_dealloc(dbg, llbuf, DW_DLA_LOCDESC);
       
   378 		    }
       
   379 		} else {
       
   380 		    retval = res;
       
   381 		}
       
   382 		break;
       
   383 
       
   384 	    default:
       
   385 		/* must be a const offset in debug_loc */
       
   386 		;		/* do nothing */
       
   387 	    }
       
   388 	    dwarf_dealloc(dbg, attr, DW_DLA_ATTR);
       
   389 	}			/* else error or no entry */
       
   390 	retval = fres;
       
   391     } else {
       
   392 	retval = ares;
       
   393     }
       
   394     return retval;
       
   395 }
       
   396 
       
   397 /*
       
   398   Return DW_DLV_OK, or DW_DLV_ERROR
       
   399 
       
   400   Handle the addrs in a single die.
       
   401 */
       
   402 static int
       
   403 process_this_die_attrs(Dwarf_Debug dbg, Dwarf_Die newdie, int *errval)
       
   404 {
       
   405     Dwarf_Error err;
       
   406     Dwarf_Half i;
       
   407     Dwarf_Half newattrnum;
       
   408     int res;
       
   409     int tres;
       
   410     Dwarf_Half ltag;
       
   411 
       
   412     Dwarf_Off doff;
       
   413     int doffres = dwarf_dieoffset(newdie, &doff, &err);
       
   414 
       
   415     if (doffres != DW_DLV_OK) {
       
   416 	if (doffres == DW_DLV_ERROR) {
       
   417 	    *errval = (int) dwarf_errno(err);
       
   418 	}
       
   419 	return doffres;
       
   420     }
       
   421     tres = dwarf_tag(newdie, &ltag, &err);
       
   422     if (tres != DW_DLV_OK) {
       
   423 	return tres;
       
   424     }
       
   425     if (DW_TAG_compile_unit == ltag) {
       
   426 	/* because of the way the dwarf_line code works, we do lines 
       
   427 	   only per compile unit. This may turn out to be wrong if
       
   428 	   we have lines left unconnected to a CU. of course such 
       
   429 	   lines will not, at present, be used by gnome. This is
       
   430 	   not ideal as coded due to the dwarf_line.c issue. */
       
   431 	int lres;
       
   432 
       
   433 	lres = handle_debug_line(dbg, newdie, send_addr_note, errval);
       
   434 	if (lres == DW_DLV_ERROR) {
       
   435 	    return lres;
       
   436 	}
       
   437     }
       
   438 
       
   439     for (i = 0; i < sizeof(might_have_addr) / sizeof(int); i++) {
       
   440 	int resattr;
       
   441 	Dwarf_Bool hasattr;
       
   442 
       
   443 	newattrnum = might_have_addr[i];
       
   444 	err = 0;
       
   445 	resattr = dwarf_hasattr(newdie, newattrnum, &hasattr, &err);
       
   446 	if (DW_DLV_OK == resattr) {
       
   447 	    if (hasattr) {
       
   448 		res = handle_attr_addr(dbg, newdie, newattrnum, &err);
       
   449 		if (res != DW_DLV_OK) {
       
   450 		    *errval = (int) dwarf_errno(err);
       
   451 		    return DW_DLV_ERROR;
       
   452 		}
       
   453 	    }
       
   454 	} else {
       
   455 	    if (resattr == DW_DLV_ERROR) {
       
   456 		*errval = (int) dwarf_errno(err);
       
   457 		return resattr;
       
   458 	    }
       
   459 	}
       
   460     }
       
   461     for (i = 0; i < sizeof(might_have_locdesc) / sizeof(int); i++) {
       
   462 	int resattr;
       
   463 	Dwarf_Bool hasattr;
       
   464 
       
   465 	newattrnum = might_have_locdesc[i];
       
   466 	err = 0;
       
   467 	resattr = dwarf_hasattr(newdie, newattrnum, &hasattr, &err);
       
   468 	if (DW_DLV_OK == resattr) {
       
   469 	    if (hasattr) {
       
   470 		res =
       
   471 		    handle_attr_locdesc(dbg, newdie, newattrnum, &err);
       
   472 		if (res != DW_DLV_OK) {
       
   473 		    *errval = (int) dwarf_errno(err);
       
   474 		    return DW_DLV_ERROR;
       
   475 		}
       
   476 	    }
       
   477 	} else {
       
   478 	    if (resattr == DW_DLV_ERROR) {
       
   479 		*errval = (int) dwarf_errno(err);
       
   480 		return resattr;
       
   481 	    }
       
   482 	}
       
   483     }
       
   484 
       
   485     return DW_DLV_OK;
       
   486 }
       
   487 
       
   488 /*
       
   489 	Handle siblings as a list,
       
   490 	Do children by recursing.
       
   491 	Effectively this is walking the tree preorder.
       
   492 
       
   493 	This dealloc's any die passed to it, so the
       
   494 	caller should not do that dealloc.
       
   495 	It seems more logical to have the one causing
       
   496 	the alloc to do the dealloc, but that way this
       
   497 	routine became a mess.
       
   498 
       
   499 */
       
   500 static int
       
   501 do_this_die_and_dealloc(Dwarf_Debug dbg, Dwarf_Die die, int *errval)
       
   502 {
       
   503 
       
   504     Dwarf_Die prevdie = 0;
       
   505     Dwarf_Die newdie = die;
       
   506     Dwarf_Error err = 0;
       
   507     int res = 0;
       
   508     int sibres = DW_DLV_OK;
       
   509     int tres = DW_DLV_OK;
       
   510     Dwarf_Die sibdie;
       
   511 
       
   512     while (sibres == DW_DLV_OK) {
       
   513 	Dwarf_Die ch_die;
       
   514 
       
   515 
       
   516 	res = process_this_die_attrs(dbg, newdie, errval);
       
   517 	switch (res) {
       
   518 	case DW_DLV_OK:
       
   519 	    break;
       
   520 	case DW_DLV_NO_ENTRY:
       
   521 	    break;
       
   522 	default:
       
   523 	case DW_DLV_ERROR:
       
   524 	    if (prevdie) {
       
   525 		dwarf_dealloc(dbg, prevdie, DW_DLA_DIE);
       
   526 		prevdie = 0;
       
   527 	    }
       
   528 	    return DW_DLV_ERROR;
       
   529 	}
       
   530 
       
   531 	tres = dwarf_child(newdie, &ch_die, &err);
       
   532 
       
   533 	if (tres == DW_DLV_OK) {
       
   534 	    res = do_this_die_and_dealloc(dbg, ch_die, errval);
       
   535 	    switch (res) {
       
   536 	    case DW_DLV_OK:
       
   537 		break;
       
   538 	    case DW_DLV_NO_ENTRY:
       
   539 		break;
       
   540 	    default:
       
   541 	    case DW_DLV_ERROR:
       
   542 		if (prevdie) {
       
   543 		    dwarf_dealloc(dbg, prevdie, DW_DLA_DIE);
       
   544 		    prevdie = 0;
       
   545 		}
       
   546 		return DW_DLV_ERROR;
       
   547 	    }
       
   548 	} else if (tres == DW_DLV_ERROR) {
       
   549 	    /* An error! */
       
   550 	    *errval = (int) dwarf_errno(err);
       
   551 	    if (prevdie) {
       
   552 		dwarf_dealloc(dbg, prevdie, DW_DLA_DIE);
       
   553 		prevdie = 0;
       
   554 	    }
       
   555 	    dwarf_dealloc(dbg, err, DW_DLA_ERROR);
       
   556 	    return DW_DLV_ERROR;
       
   557 	}			/* else was NO ENTRY */
       
   558 	prevdie = newdie;
       
   559 	sibdie = 0;
       
   560 	sibres = dwarf_siblingof(dbg, newdie, &sibdie, &err);
       
   561 	if (prevdie) {
       
   562 	    dwarf_dealloc(dbg, prevdie, DW_DLA_DIE);
       
   563 	    prevdie = 0;
       
   564 	}
       
   565 	newdie = sibdie;
       
   566 
       
   567     }
       
   568     if (sibres == DW_DLV_NO_ENTRY) {
       
   569 	return DW_DLV_OK;
       
   570     }
       
   571     /* error. */
       
   572     *errval = (int) dwarf_errno(err);
       
   573     if (prevdie) {
       
   574 	dwarf_dealloc(dbg, prevdie, DW_DLA_DIE);
       
   575 	prevdie = 0;
       
   576     }
       
   577     dwarf_dealloc(dbg, err, DW_DLA_ERROR);
       
   578     return DW_DLV_ERROR;
       
   579 
       
   580 }
       
   581 
       
   582 
       
   583 static int
       
   584 handle_debug_frame(Dwarf_Debug dbg, Dwarf_addr_callback_func cb_func,
       
   585 		   int *errval)
       
   586 {
       
   587     int retval = DW_DLV_OK;
       
   588     int res;
       
   589     Dwarf_Error err;
       
   590     Dwarf_Addr *addrlist;
       
   591     Dwarf_Off *offsetlist;
       
   592     Dwarf_Signed count;
       
   593     int i;
       
   594 
       
   595     res =
       
   596 	_dwarf_frame_address_offsets(dbg, &addrlist, &offsetlist,
       
   597 				     &count, &err);
       
   598     if (res == DW_DLV_OK) {
       
   599 	for (i = 0; i < count; i++) {
       
   600 	    cb_func(DW_SECTION_FRAME, offsetlist[i], addrlist[i]);
       
   601 	}
       
   602 	dwarf_dealloc(dbg, offsetlist, DW_DLA_ADDR);
       
   603 	dwarf_dealloc(dbg, addrlist, DW_DLA_ADDR);
       
   604     } else if (res == DW_DLV_NO_ENTRY) {
       
   605 	retval = res;
       
   606     } else {
       
   607 	*errval = (int) dwarf_errno(err);
       
   608 	retval = DW_DLV_ERROR;
       
   609     }
       
   610     return retval;
       
   611 
       
   612 }
       
   613 static int
       
   614 handle_debug_aranges(Dwarf_Debug dbg, Dwarf_addr_callback_func cb_func,
       
   615 		     int *errval)
       
   616 {
       
   617     int retval = DW_DLV_OK;
       
   618     Dwarf_Error err;
       
   619     Dwarf_Addr *aranges;
       
   620     Dwarf_Signed count;
       
   621     int indx;
       
   622     Dwarf_Off *offsets;
       
   623 
       
   624     retval =
       
   625 	_dwarf_get_aranges_addr_offsets(dbg, &aranges, &offsets, &count,
       
   626 					&err);
       
   627     if (retval == DW_DLV_OK) {
       
   628 	if (count == 0) {
       
   629 	    retval = DW_DLV_NO_ENTRY;
       
   630 	} else {
       
   631 	    for (indx = 0; indx < count; indx++) {
       
   632 		cb_func(DW_SECTION_ARANGES, offsets[indx],
       
   633 			aranges[indx]);
       
   634 	    }
       
   635 	}
       
   636 	dwarf_dealloc(dbg, aranges, DW_DLA_ADDR);
       
   637 	dwarf_dealloc(dbg, offsets, DW_DLA_ADDR);
       
   638     } else if (retval == DW_DLV_NO_ENTRY) {
       
   639 	;			/* do nothing */
       
   640     } else {
       
   641 	*errval = (int) dwarf_errno(err);
       
   642 	retval = DW_DLV_ERROR;
       
   643     }
       
   644     return retval;
       
   645 }
       
   646 static int
       
   647 handle_debug_line(Dwarf_Debug dbg, Dwarf_Die cu_die,
       
   648 		  Dwarf_addr_callback_func cb_func, int *errval)
       
   649 {
       
   650     int retval = DW_DLV_OK;
       
   651     int res;
       
   652     Dwarf_Error err;
       
   653     Dwarf_Addr *addrlist;
       
   654     Dwarf_Off *offsetlist;
       
   655     Dwarf_Unsigned count;
       
   656     Dwarf_Unsigned i;
       
   657 
       
   658     res =
       
   659 	_dwarf_line_address_offsets(dbg, cu_die, &addrlist, &offsetlist,
       
   660 				    &count, &err);
       
   661     if (res == DW_DLV_OK) {
       
   662 	for (i = 0; i < count; i++) {
       
   663 	    cb_func(DW_SECTION_LINE, offsetlist[i], addrlist[i]);
       
   664 
       
   665 	}
       
   666 	dwarf_dealloc(dbg, offsetlist, DW_DLA_ADDR);
       
   667 	dwarf_dealloc(dbg, addrlist, DW_DLA_ADDR);
       
   668     } else if (res == DW_DLV_NO_ENTRY) {
       
   669 	retval = res;
       
   670     } else {
       
   671 	*errval = (int) dwarf_errno(err);
       
   672 	retval = DW_DLV_ERROR;
       
   673     }
       
   674     return retval;
       
   675 }
       
   676 
       
   677 /*
       
   678 	We need to add support for this. Currently we do not
       
   679 	generate this section.
       
   680 	FIX!
       
   681 */
       
   682 static int
       
   683 handle_debug_loc(void)
       
   684 {
       
   685     int retval = DW_DLV_NO_ENTRY;
       
   686 
       
   687     return retval;
       
   688 }