tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_loc.c
changeset 34 92d87f2e53c2
equal deleted inserted replaced
33:1af5c1be89f8 34:92d87f2e53c2
       
     1 /*
       
     2 
       
     3   Copyright (C) 2000,2003,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 #include "config.h"
       
    46 #include "dwarf_incl.h"
       
    47 #include "dwarf_loc.h"
       
    48 
       
    49 
       
    50 /*
       
    51     Given a Dwarf_Block that represents a location expression,
       
    52     this function returns a pointer to a Dwarf_Locdesc struct 
       
    53     that has its ld_cents field set to the number of location 
       
    54     operators in the block, and its ld_s field pointing to a 
       
    55     contiguous block of Dwarf_Loc structs.  However, the 
       
    56     ld_lopc and ld_hipc values are uninitialized.  Returns 
       
    57     NULL on error.  This function assumes that the length of 
       
    58     the block is greater than 0.  Zero length location expressions 
       
    59     to represent variables that have been optimized away are 
       
    60     handled in the calling function.
       
    61 */
       
    62 static Dwarf_Locdesc *
       
    63 _dwarf_get_locdesc(Dwarf_Debug dbg,
       
    64 		   Dwarf_Block * loc_block,
       
    65 		   Dwarf_Addr lowpc,
       
    66 		   Dwarf_Addr highpc, Dwarf_Error * error)
       
    67 {
       
    68     /* Size of the block containing the location expression. */
       
    69     Dwarf_Unsigned loc_len = 0;
       
    70 
       
    71     /* Sweeps the block containing the location expression. */
       
    72     Dwarf_Small *loc_ptr = 0;
       
    73 
       
    74     /* Current location operator. */
       
    75     Dwarf_Small atom = 0;
       
    76 
       
    77     /* Offset of current operator from start of block. */
       
    78     Dwarf_Unsigned offset = 0;
       
    79 
       
    80     /* Operands of current location operator. */
       
    81     Dwarf_Unsigned operand1, operand2;
       
    82 
       
    83     /* Used to chain the Dwarf_Loc_Chain_s structs. */
       
    84     Dwarf_Loc_Chain curr_loc = NULL;
       
    85     Dwarf_Loc_Chain prev_loc = NULL;
       
    86     Dwarf_Loc_Chain head_loc = NULL;
       
    87 
       
    88     /* Count of the number of location operators. */
       
    89     Dwarf_Unsigned op_count = 0;
       
    90 
       
    91     /* Contiguous block of Dwarf_Loc's for Dwarf_Locdesc. */
       
    92     Dwarf_Loc *block_loc = 0;
       
    93 
       
    94     /* Dwarf_Locdesc pointer to be returned. */
       
    95     Dwarf_Locdesc *locdesc = 0;
       
    96 
       
    97     Dwarf_Word leb128_length = 0;
       
    98     Dwarf_Unsigned i = 0;
       
    99 
       
   100     /* ***** BEGIN CODE ***** */
       
   101 
       
   102     loc_len = loc_block->bl_len;
       
   103     loc_ptr = loc_block->bl_data;
       
   104 
       
   105     offset = 0;
       
   106     op_count = 0;
       
   107     while (offset < loc_len) {
       
   108 
       
   109 	operand1 = 0;
       
   110 	operand2 = 0;
       
   111 	op_count++;
       
   112 
       
   113 	atom = *(Dwarf_Small *) loc_ptr;
       
   114 	loc_ptr++;
       
   115 	offset++;
       
   116 
       
   117 	curr_loc =
       
   118 	    (Dwarf_Loc_Chain) _dwarf_get_alloc(dbg, DW_DLA_LOC_CHAIN,
       
   119 					       1);
       
   120 	if (curr_loc == NULL) {
       
   121 	    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
       
   122 	    return (NULL);
       
   123 	}
       
   124 	curr_loc->lc_offset = offset;
       
   125 	curr_loc->lc_atom = atom;
       
   126 	switch (atom) {
       
   127 
       
   128 	case DW_OP_reg0:
       
   129 	case DW_OP_reg1:
       
   130 	case DW_OP_reg2:
       
   131 	case DW_OP_reg3:
       
   132 	case DW_OP_reg4:
       
   133 	case DW_OP_reg5:
       
   134 	case DW_OP_reg6:
       
   135 	case DW_OP_reg7:
       
   136 	case DW_OP_reg8:
       
   137 	case DW_OP_reg9:
       
   138 	case DW_OP_reg10:
       
   139 	case DW_OP_reg11:
       
   140 	case DW_OP_reg12:
       
   141 	case DW_OP_reg13:
       
   142 	case DW_OP_reg14:
       
   143 	case DW_OP_reg15:
       
   144 	case DW_OP_reg16:
       
   145 	case DW_OP_reg17:
       
   146 	case DW_OP_reg18:
       
   147 	case DW_OP_reg19:
       
   148 	case DW_OP_reg20:
       
   149 	case DW_OP_reg21:
       
   150 	case DW_OP_reg22:
       
   151 	case DW_OP_reg23:
       
   152 	case DW_OP_reg24:
       
   153 	case DW_OP_reg25:
       
   154 	case DW_OP_reg26:
       
   155 	case DW_OP_reg27:
       
   156 	case DW_OP_reg28:
       
   157 	case DW_OP_reg29:
       
   158 	case DW_OP_reg30:
       
   159 	case DW_OP_reg31:
       
   160 	    break;
       
   161 
       
   162 	case DW_OP_regx:
       
   163 	    operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
       
   164 	    loc_ptr = loc_ptr + leb128_length;
       
   165 	    offset = offset + leb128_length;
       
   166 	    break;
       
   167 
       
   168 	case DW_OP_lit0:
       
   169 	case DW_OP_lit1:
       
   170 	case DW_OP_lit2:
       
   171 	case DW_OP_lit3:
       
   172 	case DW_OP_lit4:
       
   173 	case DW_OP_lit5:
       
   174 	case DW_OP_lit6:
       
   175 	case DW_OP_lit7:
       
   176 	case DW_OP_lit8:
       
   177 	case DW_OP_lit9:
       
   178 	case DW_OP_lit10:
       
   179 	case DW_OP_lit11:
       
   180 	case DW_OP_lit12:
       
   181 	case DW_OP_lit13:
       
   182 	case DW_OP_lit14:
       
   183 	case DW_OP_lit15:
       
   184 	case DW_OP_lit16:
       
   185 	case DW_OP_lit17:
       
   186 	case DW_OP_lit18:
       
   187 	case DW_OP_lit19:
       
   188 	case DW_OP_lit20:
       
   189 	case DW_OP_lit21:
       
   190 	case DW_OP_lit22:
       
   191 	case DW_OP_lit23:
       
   192 	case DW_OP_lit24:
       
   193 	case DW_OP_lit25:
       
   194 	case DW_OP_lit26:
       
   195 	case DW_OP_lit27:
       
   196 	case DW_OP_lit28:
       
   197 	case DW_OP_lit29:
       
   198 	case DW_OP_lit30:
       
   199 	case DW_OP_lit31:
       
   200 	    operand1 = atom - DW_OP_lit0;
       
   201 	    break;
       
   202 
       
   203 	case DW_OP_addr:
       
   204 	    READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned,
       
   205 			   loc_ptr, dbg->de_pointer_size);
       
   206 	    loc_ptr += dbg->de_pointer_size;
       
   207 	    offset += dbg->de_pointer_size;
       
   208 	    break;
       
   209 
       
   210 	case DW_OP_const1u:
       
   211 	    operand1 = *(Dwarf_Small *) loc_ptr;
       
   212 	    loc_ptr = loc_ptr + 1;
       
   213 	    offset = offset + 1;
       
   214 	    break;
       
   215 
       
   216 	case DW_OP_const1s:
       
   217 	    operand1 = *(Dwarf_Sbyte *) loc_ptr;
       
   218             SIGN_EXTEND(operand1,1);
       
   219 	    loc_ptr = loc_ptr + 1;
       
   220 	    offset = offset + 1;
       
   221 	    break;
       
   222 
       
   223 	case DW_OP_const2u:
       
   224 	    READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2);
       
   225 	    loc_ptr = loc_ptr + 2;
       
   226 	    offset = offset + 2;
       
   227 	    break;
       
   228 
       
   229 	case DW_OP_const2s:
       
   230 	    READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2);
       
   231             SIGN_EXTEND(operand1,2);
       
   232 	    loc_ptr = loc_ptr + 2;
       
   233 	    offset = offset + 2;
       
   234 	    break;
       
   235 
       
   236 	case DW_OP_const4u:
       
   237 	    READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 4);
       
   238 	    loc_ptr = loc_ptr + 4;
       
   239 	    offset = offset + 4;
       
   240 	    break;
       
   241 
       
   242 	case DW_OP_const4s:
       
   243 	    READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 4);
       
   244             SIGN_EXTEND(operand1,4);
       
   245 	    loc_ptr = loc_ptr + 4;
       
   246 	    offset = offset + 4;
       
   247 	    break;
       
   248 
       
   249 	case DW_OP_const8u:
       
   250 	    READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 8);
       
   251 	    loc_ptr = loc_ptr + 8;
       
   252 	    offset = offset + 8;
       
   253 	    break;
       
   254 
       
   255 	case DW_OP_const8s:
       
   256 	    READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 8);
       
   257 	    loc_ptr = loc_ptr + 8;
       
   258 	    offset = offset + 8;
       
   259 	    break;
       
   260 
       
   261 	case DW_OP_constu:
       
   262 	    operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
       
   263 	    loc_ptr = loc_ptr + leb128_length;
       
   264 	    offset = offset + leb128_length;
       
   265 	    break;
       
   266 
       
   267 	case DW_OP_consts:
       
   268 	    operand1 = _dwarf_decode_s_leb128(loc_ptr, &leb128_length);
       
   269 	    loc_ptr = loc_ptr + leb128_length;
       
   270 	    offset = offset + leb128_length;
       
   271 	    break;
       
   272 
       
   273 	case DW_OP_fbreg:
       
   274 	    operand1 = _dwarf_decode_s_leb128(loc_ptr, &leb128_length);
       
   275 	    loc_ptr = loc_ptr + leb128_length;
       
   276 	    offset = offset + leb128_length;
       
   277 	    break;
       
   278 
       
   279 	case DW_OP_breg0:
       
   280 	case DW_OP_breg1:
       
   281 	case DW_OP_breg2:
       
   282 	case DW_OP_breg3:
       
   283 	case DW_OP_breg4:
       
   284 	case DW_OP_breg5:
       
   285 	case DW_OP_breg6:
       
   286 	case DW_OP_breg7:
       
   287 	case DW_OP_breg8:
       
   288 	case DW_OP_breg9:
       
   289 	case DW_OP_breg10:
       
   290 	case DW_OP_breg11:
       
   291 	case DW_OP_breg12:
       
   292 	case DW_OP_breg13:
       
   293 	case DW_OP_breg14:
       
   294 	case DW_OP_breg15:
       
   295 	case DW_OP_breg16:
       
   296 	case DW_OP_breg17:
       
   297 	case DW_OP_breg18:
       
   298 	case DW_OP_breg19:
       
   299 	case DW_OP_breg20:
       
   300 	case DW_OP_breg21:
       
   301 	case DW_OP_breg22:
       
   302 	case DW_OP_breg23:
       
   303 	case DW_OP_breg24:
       
   304 	case DW_OP_breg25:
       
   305 	case DW_OP_breg26:
       
   306 	case DW_OP_breg27:
       
   307 	case DW_OP_breg28:
       
   308 	case DW_OP_breg29:
       
   309 	case DW_OP_breg30:
       
   310 	case DW_OP_breg31:
       
   311 	    operand1 = _dwarf_decode_s_leb128(loc_ptr, &leb128_length);
       
   312 	    loc_ptr = loc_ptr + leb128_length;
       
   313 	    offset = offset + leb128_length;
       
   314 	    break;
       
   315 
       
   316 	case DW_OP_bregx:
       
   317 	    /* uleb reg num followed by sleb offset */
       
   318 	    operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
       
   319 	    loc_ptr = loc_ptr + leb128_length;
       
   320 	    offset = offset + leb128_length;
       
   321 
       
   322 	    operand2 = _dwarf_decode_s_leb128(loc_ptr, &leb128_length);
       
   323 	    loc_ptr = loc_ptr + leb128_length;
       
   324 	    offset = offset + leb128_length;
       
   325 	    break;
       
   326 
       
   327 	case DW_OP_dup:
       
   328 	case DW_OP_drop:
       
   329 	    break;
       
   330 
       
   331 	case DW_OP_pick:
       
   332 	    operand1 = *(Dwarf_Small *) loc_ptr;
       
   333 	    loc_ptr = loc_ptr + 1;
       
   334 	    offset = offset + 1;
       
   335 	    break;
       
   336 
       
   337 	case DW_OP_over:
       
   338 	case DW_OP_swap:
       
   339 	case DW_OP_rot:
       
   340 	case DW_OP_deref:
       
   341 	    break;
       
   342 
       
   343 	case DW_OP_deref_size:
       
   344 	    operand1 = *(Dwarf_Small *) loc_ptr;
       
   345 	    loc_ptr = loc_ptr + 1;
       
   346 	    offset = offset + 1;
       
   347 	    break;
       
   348 
       
   349 	case DW_OP_xderef:
       
   350 	    break;
       
   351 
       
   352 	case DW_OP_xderef_size:
       
   353 	    operand1 = *(Dwarf_Small *) loc_ptr;
       
   354 	    loc_ptr = loc_ptr + 1;
       
   355 	    offset = offset + 1;
       
   356 	    break;
       
   357 
       
   358 	case DW_OP_abs:
       
   359 	case DW_OP_and:
       
   360 	case DW_OP_div:
       
   361 	case DW_OP_minus:
       
   362 	case DW_OP_mod:
       
   363 	case DW_OP_mul:
       
   364 	case DW_OP_neg:
       
   365 	case DW_OP_not:
       
   366 	case DW_OP_or:
       
   367 	case DW_OP_plus:
       
   368 	    break;
       
   369 
       
   370 	case DW_OP_plus_uconst:
       
   371 	    operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
       
   372 	    loc_ptr = loc_ptr + leb128_length;
       
   373 	    offset = offset + leb128_length;
       
   374 	    break;
       
   375 
       
   376 	case DW_OP_shl:
       
   377 	case DW_OP_shr:
       
   378 	case DW_OP_shra:
       
   379 	case DW_OP_xor:
       
   380 	    break;
       
   381 
       
   382 	case DW_OP_le:
       
   383 	case DW_OP_ge:
       
   384 	case DW_OP_eq:
       
   385 	case DW_OP_lt:
       
   386 	case DW_OP_gt:
       
   387 	case DW_OP_ne:
       
   388 	    break;
       
   389 
       
   390 	case DW_OP_skip:
       
   391 	case DW_OP_bra:
       
   392 	    READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2);
       
   393 	    loc_ptr = loc_ptr + 2;
       
   394 	    offset = offset + 2;
       
   395 	    break;
       
   396 
       
   397 	case DW_OP_piece:
       
   398 	    operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
       
   399 	    loc_ptr = loc_ptr + leb128_length;
       
   400 	    offset = offset + leb128_length;
       
   401 	    break;
       
   402 
       
   403 	case DW_OP_nop:
       
   404 	    break;
       
   405 	case DW_OP_push_object_address:	/* DWARF3 */
       
   406 	    break;
       
   407 	case DW_OP_call2:	/* DWARF3 */
       
   408 	    READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 2);
       
   409 	    loc_ptr = loc_ptr + 2;
       
   410 	    offset = offset + 2;
       
   411 	    break;
       
   412 
       
   413 	case DW_OP_call4:	/* DWARF3 */
       
   414 	    READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr, 4);
       
   415 	    loc_ptr = loc_ptr + 4;
       
   416 	    offset = offset + 4;
       
   417 	    break;
       
   418 	case DW_OP_call_ref:	/* DWARF3 */
       
   419 	    READ_UNALIGNED(dbg, operand1, Dwarf_Unsigned, loc_ptr,
       
   420 			   dbg->de_length_size);
       
   421 	    loc_ptr = loc_ptr + dbg->de_length_size;
       
   422 	    offset = offset + dbg->de_length_size;
       
   423 	    break;
       
   424 
       
   425 	case DW_OP_form_tls_address:	/* DWARF3f */
       
   426 	    break;
       
   427 	case DW_OP_call_frame_cfa:	/* DWARF3f */
       
   428 	    break;
       
   429 	case DW_OP_bit_piece:	/* DWARF3f */
       
   430 	    /* uleb size in bits followed by uleb offset in bits */
       
   431 	    operand1 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
       
   432 	    loc_ptr = loc_ptr + leb128_length;
       
   433 	    offset = offset + leb128_length;
       
   434 
       
   435 	    operand2 = _dwarf_decode_u_leb128(loc_ptr, &leb128_length);
       
   436 	    loc_ptr = loc_ptr + leb128_length;
       
   437 	    offset = offset + leb128_length;
       
   438 	    break;
       
   439 
       
   440 
       
   441 	default:
       
   442 	    _dwarf_error(dbg, error, DW_DLE_LOC_EXPR_BAD);
       
   443 	    return (NULL);
       
   444 	}
       
   445 
       
   446 
       
   447 	curr_loc->lc_number = operand1;
       
   448 	curr_loc->lc_number2 = operand2;
       
   449 
       
   450 	if (head_loc == NULL)
       
   451 	    head_loc = prev_loc = curr_loc;
       
   452 	else {
       
   453 	    prev_loc->lc_next = curr_loc;
       
   454 	    prev_loc = curr_loc;
       
   455 	}
       
   456     }
       
   457 
       
   458     block_loc =
       
   459 	(Dwarf_Loc *) _dwarf_get_alloc(dbg, DW_DLA_LOC_BLOCK, op_count);
       
   460     if (block_loc == NULL) {
       
   461 	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
       
   462 	return (NULL);
       
   463     }
       
   464 
       
   465     curr_loc = head_loc;
       
   466     for (i = 0; i < op_count; i++) {
       
   467 	(block_loc + i)->lr_atom = curr_loc->lc_atom;
       
   468 	(block_loc + i)->lr_number = curr_loc->lc_number;
       
   469 	(block_loc + i)->lr_number2 = curr_loc->lc_number2;
       
   470 	(block_loc + i)->lr_offset = curr_loc->lc_offset;
       
   471 
       
   472 	prev_loc = curr_loc;
       
   473 	curr_loc = curr_loc->lc_next;
       
   474 	dwarf_dealloc(dbg, prev_loc, DW_DLA_LOC_CHAIN);
       
   475     }
       
   476 
       
   477     locdesc =
       
   478 	(Dwarf_Locdesc *) _dwarf_get_alloc(dbg, DW_DLA_LOCDESC, 1);
       
   479     if (locdesc == NULL) {
       
   480 	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
       
   481 	return (NULL);
       
   482     }
       
   483 
       
   484     locdesc->ld_cents = op_count;
       
   485     locdesc->ld_s = block_loc;
       
   486     locdesc->ld_from_loclist = loc_block->bl_from_loclist;
       
   487     locdesc->ld_section_offset = loc_block->bl_section_offset;
       
   488     locdesc->ld_lopc = lowpc;
       
   489     locdesc->ld_hipc = highpc;
       
   490 
       
   491     return (locdesc);
       
   492 }
       
   493 
       
   494 /* Using a loclist offset to get the in-memory
       
   495    address of .debug_loc data to read, returns the loclist 
       
   496    'header' info in return_block.
       
   497 */
       
   498 
       
   499 #define MAX_ADDR ((address_size == 8)?0xffffffffffffffffULL:0xffffffff)
       
   500 
       
   501 static int
       
   502 _dwarf_read_loc_section(Dwarf_Debug dbg,
       
   503 			Dwarf_Block * return_block,
       
   504 			Dwarf_Addr * lowpc, Dwarf_Addr * hipc,
       
   505 			Dwarf_Off sec_offset, Dwarf_Error * error)
       
   506 {
       
   507     Dwarf_Small *beg = dbg->de_debug_loc + sec_offset;
       
   508     int address_size = dbg->de_pointer_size;
       
   509 
       
   510     Dwarf_Addr start_addr = 0;
       
   511     Dwarf_Addr end_addr = 0;
       
   512     Dwarf_Half exprblock_size = 0;
       
   513     Dwarf_Unsigned exprblock_off =
       
   514 	2 * address_size + sizeof(Dwarf_Half);
       
   515 
       
   516     if (sec_offset >= dbg->de_debug_loc_size) {
       
   517 	/* We're at the end. No more present. */
       
   518 	return DW_DLV_NO_ENTRY;
       
   519     }
       
   520 
       
   521     /* If it goes past end, error */
       
   522     if (exprblock_off > dbg->de_debug_loc_size) {
       
   523 	_dwarf_error(NULL, error, DW_DLE_DEBUG_LOC_SECTION_SHORT);
       
   524 	return DW_DLV_ERROR;
       
   525     }
       
   526 
       
   527     READ_UNALIGNED(dbg, start_addr, Dwarf_Addr, beg, address_size);
       
   528     READ_UNALIGNED(dbg, end_addr, Dwarf_Addr,
       
   529 		   beg + address_size, address_size);
       
   530     if (start_addr == 0 && end_addr == 0) {
       
   531 	/* If start_addr and end_addr are 0, it's the end and no
       
   532 	   exprblock_size field follows. */
       
   533 	exprblock_size = 0;
       
   534 	exprblock_off -= sizeof(Dwarf_Half);
       
   535     } else if (start_addr == MAX_ADDR) {
       
   536 	/* end address is a base address, no exprblock_size field here
       
   537 	   either */
       
   538 	exprblock_size = 0;
       
   539 	exprblock_off -= sizeof(Dwarf_Half);
       
   540     } else {
       
   541 
       
   542 	READ_UNALIGNED(dbg, exprblock_size, Dwarf_Half,
       
   543 		       beg + 2 * address_size, sizeof(Dwarf_Half));
       
   544 	/* exprblock_size can be zero, means no expression */
       
   545 	if ((exprblock_off + exprblock_size) > dbg->de_debug_loc_size) {
       
   546 	    _dwarf_error(NULL, error, DW_DLE_DEBUG_LOC_SECTION_SHORT);
       
   547 	    return DW_DLV_ERROR;
       
   548 	}
       
   549     }
       
   550 #undef MAX_ADDR
       
   551     *lowpc = start_addr;
       
   552     *hipc = end_addr;
       
   553 
       
   554     return_block->bl_len = exprblock_size;
       
   555     return_block->bl_from_loclist = 1;
       
   556     return_block->bl_data = beg + exprblock_off;
       
   557     return_block->bl_section_offset =
       
   558 	((Dwarf_Small *) return_block->bl_data) - dbg->de_debug_loc;
       
   559 
       
   560     return DW_DLV_OK;
       
   561 
       
   562 }
       
   563 static int
       
   564 _dwarf_get_loclist_count(Dwarf_Debug dbg,
       
   565 			 Dwarf_Off loclist_offset,
       
   566 			 int *loclist_count, Dwarf_Error * error)
       
   567 {
       
   568     int count = 0;
       
   569     Dwarf_Off offset = loclist_offset;
       
   570 
       
   571 
       
   572     for (;;) {
       
   573 	Dwarf_Block b;
       
   574 	Dwarf_Addr lowpc;
       
   575 	Dwarf_Addr highpc;
       
   576 	int res = _dwarf_read_loc_section(dbg, &b,
       
   577 
       
   578 					  &lowpc, &highpc,
       
   579 					  offset, error);
       
   580 
       
   581 	if (res != DW_DLV_OK) {
       
   582 	    return res;
       
   583 	}
       
   584 	offset = b.bl_len + b.bl_section_offset;
       
   585 	if (lowpc == 0 && highpc == 0) {
       
   586 	    break;
       
   587 	}
       
   588 	count++;
       
   589     }
       
   590     *loclist_count = count;
       
   591     return DW_DLV_OK;
       
   592 }
       
   593 
       
   594 /* Helper routine to avoid code duplication. 
       
   595 */
       
   596 static int
       
   597 _dwarf_setup_loc(Dwarf_Attribute attr,
       
   598 		 Dwarf_Debug * dbg_ret,
       
   599 		 Dwarf_Half * form_ret, Dwarf_Error * error)
       
   600 {
       
   601     Dwarf_Debug dbg = 0;
       
   602     Dwarf_Half form = 0;
       
   603     int blkres;
       
   604 
       
   605     if (attr == NULL) {
       
   606 	_dwarf_error(NULL, error, DW_DLE_ATTR_NULL);
       
   607 	return (DW_DLV_ERROR);
       
   608     }
       
   609     if (attr->ar_cu_context == NULL) {
       
   610 	_dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT);
       
   611 	return (DW_DLV_ERROR);
       
   612     }
       
   613 
       
   614     dbg = attr->ar_cu_context->cc_dbg;
       
   615     if (dbg == NULL) {
       
   616 	_dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL);
       
   617 	return (DW_DLV_ERROR);
       
   618     }
       
   619     *dbg_ret = dbg;
       
   620     blkres = dwarf_whatform(attr, &form, error);
       
   621     if (blkres != DW_DLV_OK) {
       
   622 	_dwarf_error(dbg, error, DW_DLE_LOC_EXPR_BAD);
       
   623 	return blkres;
       
   624     }
       
   625     *form_ret = form;
       
   626 
       
   627     return DW_DLV_OK;
       
   628 }
       
   629 
       
   630 /* Helper routine  to avoid code duplication.
       
   631 */
       
   632 static int
       
   633 _dwarf_get_loclist_header_start(Dwarf_Debug dbg,
       
   634 				Dwarf_Attribute attr,
       
   635 				Dwarf_Unsigned * loclist_offset,
       
   636 				Dwarf_Error * error)
       
   637 {
       
   638     int secload = 0;
       
   639     int blkres = dwarf_formudata(attr, loclist_offset, error);
       
   640 
       
   641     if (blkres != DW_DLV_OK) {
       
   642 	return (blkres);
       
   643     }
       
   644 
       
   645     if (!dbg->de_debug_loc) {
       
   646 	secload = _dwarf_load_section(dbg,
       
   647 				      dbg->de_debug_loc_index,
       
   648 				      &dbg->de_debug_loc, error);
       
   649 	if (secload != DW_DLV_OK) {
       
   650 	    return secload;
       
   651 	}
       
   652     }
       
   653     return DW_DLV_OK;
       
   654 }
       
   655 
       
   656 /* When llbuf (see dwarf_loclist_n) is partially set up
       
   657    and an error is encountered, tear it down as it
       
   658    won't be used.
       
   659 */
       
   660 static void
       
   661 _dwarf_cleanup_llbuf(Dwarf_Debug dbg, Dwarf_Locdesc ** llbuf, int count)
       
   662 {
       
   663     int i;
       
   664 
       
   665     for (i = 0; i < count; ++i) {
       
   666 	dwarf_dealloc(dbg, llbuf[i]->ld_s, DW_DLA_LOC_BLOCK);
       
   667 	dwarf_dealloc(dbg, llbuf[i], DW_DLA_LOCDESC);
       
   668     }
       
   669     dwarf_dealloc(dbg, llbuf, DW_DLA_LIST);
       
   670 }
       
   671 
       
   672 /* 
       
   673 	Handles simple location entries and loclists.
       
   674 	Returns all the Locdesc's thru llbuf. 
       
   675 	
       
   676 */
       
   677 int
       
   678 dwarf_loclist_n(Dwarf_Attribute attr,
       
   679 		Dwarf_Locdesc *** llbuf_out,
       
   680 		Dwarf_Signed * listlen_out, Dwarf_Error * error)
       
   681 {
       
   682     Dwarf_Debug dbg;
       
   683 
       
   684     /* 
       
   685        Dwarf_Attribute that describes the DW_AT_location in die, if
       
   686        present. */
       
   687     Dwarf_Attribute loc_attr = attr;
       
   688 
       
   689     /* Dwarf_Block that describes a single location expression. */
       
   690     Dwarf_Block loc_block;
       
   691 
       
   692     /* A pointer to the current Dwarf_Locdesc read. */
       
   693     Dwarf_Locdesc *locdesc = 0;
       
   694 
       
   695     Dwarf_Half form = 0;
       
   696     Dwarf_Addr lowpc = 0;
       
   697     Dwarf_Addr highpc = 0;
       
   698     Dwarf_Signed listlen = 0;
       
   699     Dwarf_Locdesc **llbuf = 0;
       
   700 
       
   701     int blkres;
       
   702     int setup_res;
       
   703 
       
   704     /* ***** BEGIN CODE ***** */
       
   705     setup_res = _dwarf_setup_loc(attr, &dbg, &form, error);
       
   706     if (setup_res != DW_DLV_OK) {
       
   707 	return setup_res;
       
   708     }
       
   709     /* If this is a form_block then it's a location expression. If it's 
       
   710        DW_FORM_data4 or DW_FORM_data8 it's a loclist offset */
       
   711     if (form == DW_FORM_data4 || form == DW_FORM_data8) {
       
   712 
       
   713 	/* A reference to .debug_loc, with an offset in .debug_loc of a 
       
   714 	   loclist */
       
   715 	Dwarf_Unsigned loclist_offset = 0;
       
   716 	int off_res;
       
   717 	int count_res;
       
   718 	int loclist_count;
       
   719 	int lli;
       
   720 
       
   721 	off_res = _dwarf_get_loclist_header_start(dbg,
       
   722 						  attr, &loclist_offset,
       
   723 						  error);
       
   724 	if (off_res != DW_DLV_OK) {
       
   725 	    return off_res;
       
   726 	}
       
   727 	count_res = _dwarf_get_loclist_count(dbg, loclist_offset,
       
   728 					     &loclist_count, error);
       
   729 	listlen = loclist_count;
       
   730 	if (count_res != DW_DLV_OK) {
       
   731 	    return count_res;
       
   732 	}
       
   733 	if (loclist_count == 0) {
       
   734 	    return DW_DLV_NO_ENTRY;
       
   735 	}
       
   736 
       
   737 	llbuf = (Dwarf_Locdesc **)
       
   738 	    _dwarf_get_alloc(dbg, DW_DLA_LIST, loclist_count);
       
   739 	if (!llbuf) {
       
   740 	    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
       
   741 	    return (DW_DLV_ERROR);
       
   742 	}
       
   743 
       
   744 	for (lli = 0; lli < loclist_count; ++lli) {
       
   745 	    blkres = _dwarf_read_loc_section(dbg, &loc_block,
       
   746 					     &lowpc,
       
   747 					     &highpc,
       
   748 					     loclist_offset, error);
       
   749 	    if (blkres != DW_DLV_OK) {
       
   750 		_dwarf_cleanup_llbuf(dbg, llbuf, lli);
       
   751 		return (blkres);
       
   752 	    }
       
   753 	    locdesc = _dwarf_get_locdesc(dbg, &loc_block,
       
   754 					 lowpc, highpc, error);
       
   755 	    if (locdesc == NULL) {
       
   756 		_dwarf_cleanup_llbuf(dbg, llbuf, lli);
       
   757 		/* low level error already set: let it be passed back */
       
   758 		return (DW_DLV_ERROR);
       
   759 	    }
       
   760 	    llbuf[lli] = locdesc;
       
   761 
       
   762 	    /* Now get to next loclist entry offset. */
       
   763 	    loclist_offset = loc_block.bl_section_offset +
       
   764 		loc_block.bl_len;
       
   765 	}
       
   766 
       
   767 
       
   768     } else {
       
   769 	Dwarf_Block *tblock = 0;
       
   770 
       
   771 	blkres = dwarf_formblock(loc_attr, &tblock, error);
       
   772 	if (blkres != DW_DLV_OK) {
       
   773 	    return (blkres);
       
   774 	}
       
   775 	loc_block = *tblock;
       
   776 	/* We copied tblock contents to the stack var, so can dealloc
       
   777 	   tblock now.  Avoids leaks. */
       
   778 	dwarf_dealloc(dbg, tblock, DW_DLA_BLOCK);
       
   779 	listlen = 1;		/* One by definition of a location
       
   780 				   entry. */
       
   781 	lowpc = 0;		/* HACK */
       
   782 	highpc = (Dwarf_Unsigned) (-1LL);	/* HACK */
       
   783 
       
   784 	/* An empty location description (block length 0) means the
       
   785 	   code generator emitted no variable, the variable was not
       
   786 	   generated, it was unused or perhaps never tested after being 
       
   787 	   set. Dwarf2, section 2.4.1 In other words, it is not an
       
   788 	   error, and we don't test for block length 0 specially here. */
       
   789 	locdesc = _dwarf_get_locdesc(dbg, &loc_block,
       
   790 				     lowpc, highpc, error);
       
   791 	if (locdesc == NULL) {
       
   792 	    /* low level error already set: let it be passed back */
       
   793 	    return (DW_DLV_ERROR);
       
   794 	}
       
   795 	llbuf = (Dwarf_Locdesc **)
       
   796 	    _dwarf_get_alloc(dbg, DW_DLA_LIST, listlen);
       
   797 	if (!llbuf) {
       
   798 	    /* Free the locdesc we allocated but won't use. */
       
   799 	    dwarf_dealloc(dbg, locdesc, DW_DLA_LOCDESC);
       
   800 	    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
       
   801 	    return (DW_DLV_ERROR);
       
   802 	}
       
   803 	llbuf[0] = locdesc;
       
   804     }
       
   805 
       
   806     *llbuf_out = llbuf;
       
   807     *listlen_out = listlen;
       
   808     return (DW_DLV_OK);
       
   809 }
       
   810 
       
   811 
       
   812 /* 
       
   813 	Handles only a location expression.
       
   814 	If called on a loclist, just returns one of those.
       
   815 	Cannot not handle a real loclist. 
       
   816  	It returns the location expression as a loclist with
       
   817 	a single entry.
       
   818 	See dwarf_loclist_n() which handles any number
       
   819         of location list entries.
       
   820 
       
   821 	This is the original definition, and it simply
       
   822 	does not work for loclists. Kept for compatibility.
       
   823 */
       
   824 int
       
   825 dwarf_loclist(Dwarf_Attribute attr,
       
   826 	      Dwarf_Locdesc ** llbuf,
       
   827 	      Dwarf_Signed * listlen, Dwarf_Error * error)
       
   828 {
       
   829     Dwarf_Debug dbg;
       
   830 
       
   831     /* 
       
   832        Dwarf_Attribute that describes the DW_AT_location in die, if
       
   833        present. */
       
   834     Dwarf_Attribute loc_attr = attr;
       
   835 
       
   836     /* Dwarf_Block that describes a single location expression. */
       
   837     Dwarf_Block loc_block;
       
   838 
       
   839     /* A pointer to the current Dwarf_Locdesc read. */
       
   840     Dwarf_Locdesc *locdesc = 0;
       
   841 
       
   842     Dwarf_Half form = 0;
       
   843     Dwarf_Addr lowpc = 0;
       
   844     Dwarf_Addr highpc = 0;
       
   845 
       
   846     int blkres;
       
   847     int setup_res;
       
   848 
       
   849     /* ***** BEGIN CODE ***** */
       
   850     setup_res = _dwarf_setup_loc(attr, &dbg, &form, error);
       
   851     if (setup_res != DW_DLV_OK) {
       
   852 	return setup_res;
       
   853     }
       
   854     /* If this is a form_block then it's a location expression. If it's 
       
   855        DW_FORM_data4 or DW_FORM_data8 it's a loclist offset */
       
   856     if (form == DW_FORM_data4 || form == DW_FORM_data8) {
       
   857 
       
   858 	/* A reference to .debug_loc, with an offset in .debug_loc of a 
       
   859 	   loclist */
       
   860 	Dwarf_Unsigned loclist_offset = 0;
       
   861 	int off_res;
       
   862 
       
   863 	off_res = _dwarf_get_loclist_header_start(dbg,
       
   864 						  attr, &loclist_offset,
       
   865 						  error);
       
   866 	if (off_res != DW_DLV_OK) {
       
   867 	    return off_res;
       
   868 	}
       
   869 
       
   870 	/* With dwarf_loclist, just read a single entry */
       
   871 	blkres = _dwarf_read_loc_section(dbg, &loc_block,
       
   872 					 &lowpc,
       
   873 					 &highpc,
       
   874 					 loclist_offset, error);
       
   875 	if (blkres != DW_DLV_OK) {
       
   876 	    return (blkres);
       
   877 	}
       
   878 
       
   879 
       
   880 
       
   881 
       
   882     } else {
       
   883 	Dwarf_Block *tblock = 0;
       
   884 
       
   885 	blkres = dwarf_formblock(loc_attr, &tblock, error);
       
   886 	if (blkres != DW_DLV_OK) {
       
   887 	    return (blkres);
       
   888 	}
       
   889 	loc_block = *tblock;
       
   890 	/* We copied tblock contents to the stack var, so can dealloc
       
   891 	   tblock now.  Avoids leaks. */
       
   892 	dwarf_dealloc(dbg, tblock, DW_DLA_BLOCK);
       
   893 	lowpc = 0;		/* HACK */
       
   894 	highpc = (Dwarf_Unsigned) (-1LL);	/* HACK */
       
   895     }
       
   896 
       
   897     /* An empty location description (block length 0) means the code
       
   898        generator emitted no variable, the variable was not generated,
       
   899        it was unused or perhaps never tested after being set. Dwarf2,
       
   900        section 2.4.1 In other words, it is not an error, and we don't
       
   901        test for block length 0 specially here. FIXME: doing this once
       
   902        is wrong, needs to handle low/hi pc sets. */
       
   903     locdesc = _dwarf_get_locdesc(dbg, &loc_block, lowpc, highpc, error);
       
   904     if (locdesc == NULL) {
       
   905 	/* low level error already set: let it be passed back */
       
   906 	return (DW_DLV_ERROR);
       
   907     }
       
   908 
       
   909     *llbuf = locdesc;
       
   910     *listlen = 1;
       
   911     return (DW_DLV_OK);
       
   912 }
       
   913 
       
   914 
       
   915 
       
   916 /* 
       
   917 	Handles only a location expression.
       
   918  	It returns the location expression as a loclist with
       
   919 	a single entry.
       
   920 
       
   921         Usable to access dwarf expressions from any source, but
       
   922         specifically from
       
   923             DW_CFA_def_cfa_expression
       
   924             DW_CFA_expression
       
   925             DW_CFA_val_expression
       
   926  
       
   927         expression_in must point to a valid dwarf expression
       
   928         set of bytes of length expression_length. Not
       
   929         a DW_FORM_block*, just the expression bytes.
       
   930 
       
   931 */
       
   932 int
       
   933 dwarf_loclist_from_expr(Dwarf_Debug dbg,
       
   934               Dwarf_Ptr expression_in,
       
   935               Dwarf_Unsigned expression_length,
       
   936 	      Dwarf_Locdesc ** llbuf,
       
   937 	      Dwarf_Signed * listlen, Dwarf_Error * error)
       
   938 {
       
   939     /* Dwarf_Block that describes a single location expression. */
       
   940     Dwarf_Block loc_block;
       
   941 
       
   942     /* A pointer to the current Dwarf_Locdesc read. */
       
   943     Dwarf_Locdesc *locdesc = 0;
       
   944     Dwarf_Addr lowpc = 0;
       
   945     Dwarf_Addr highpc = (Dwarf_Unsigned) (-1LL);
       
   946 
       
   947     memset(&loc_block,0,sizeof(loc_block));
       
   948     loc_block.bl_len = expression_length;
       
   949     loc_block.bl_data = expression_in;
       
   950     loc_block.bl_from_loclist = 0; /* Not from loclist. */
       
   951     loc_block.bl_section_offset = 0; /* Fake. Not meaningful. */
       
   952 
       
   953 
       
   954     /* An empty location description (block length 0) means the code
       
   955     generator emitted no variable, the variable was not generated,
       
   956     it was unused or perhaps never tested after being set. Dwarf2,
       
   957     section 2.4.1 In other words, it is not an error, and we don't
       
   958     test for block length 0 specially here.  */
       
   959     locdesc = _dwarf_get_locdesc(dbg, &loc_block, lowpc, highpc, error);
       
   960     if (locdesc == NULL) {
       
   961         /* low level error already set: let it be passed back */
       
   962         return (DW_DLV_ERROR);
       
   963     }
       
   964 
       
   965     *llbuf = locdesc;
       
   966     *listlen = 1;
       
   967     return (DW_DLV_OK);
       
   968 }
       
   969 
       
   970 /* Usable to read a single loclist or to read a block of them
       
   971    or to read an entire section's loclists.
       
   972 
       
   973 */
       
   974 
       
   975  /*ARGSUSED*/ int
       
   976 dwarf_get_loclist_entry(Dwarf_Debug dbg,
       
   977 			Dwarf_Unsigned offset,
       
   978 			Dwarf_Addr * hipc_offset,
       
   979 			Dwarf_Addr * lopc_offset,
       
   980 			Dwarf_Ptr * data,
       
   981 			Dwarf_Unsigned * entry_len,
       
   982 			Dwarf_Unsigned * next_entry,
       
   983 			Dwarf_Error * error)
       
   984 {
       
   985     Dwarf_Block b;
       
   986     Dwarf_Addr lowpc;
       
   987     Dwarf_Addr highpc;
       
   988     int res;
       
   989 
       
   990     if (!dbg->de_debug_loc) {
       
   991 	int secload = _dwarf_load_section(dbg,
       
   992 					  dbg->de_debug_loc_index,
       
   993 					  &dbg->de_debug_loc,
       
   994 					  error);
       
   995 
       
   996 	if (secload != DW_DLV_OK) {
       
   997 	    return secload;
       
   998 	}
       
   999     }
       
  1000 
       
  1001     res = _dwarf_read_loc_section(dbg,
       
  1002 				  &b, &lowpc, &highpc, offset, error);
       
  1003     if (res != DW_DLV_OK) {
       
  1004 	return res;
       
  1005     }
       
  1006     *hipc_offset = highpc;
       
  1007     *lopc_offset = lowpc;
       
  1008     *entry_len = b.bl_len;
       
  1009     *data = b.bl_data;
       
  1010     *next_entry = b.bl_len + b.bl_section_offset;
       
  1011 
       
  1012     return DW_DLV_OK;
       
  1013 
       
  1014 
       
  1015 
       
  1016 }
       
  1017 
       
  1018