tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_arange.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   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 }