tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_frame.c
changeset 34 92d87f2e53c2
equal deleted inserted replaced
33:1af5c1be89f8 34:92d87f2e53c2
       
     1 /*
       
     2 
       
     3   Copyright (C) 2000,2002,2004,2005,2006 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 #include "config.h"
       
    47 #include "dwarf_incl.h"
       
    48 #include <stdio.h>
       
    49 #include <stdlib.h>
       
    50 #include "dwarf_frame.h"
       
    51 #include "dwarf_arange.h"	/* Using Arange as a way to build a
       
    52 				   list */
       
    53 
       
    54 #define FDE_NULL_CHECKS_AND_SET_DBG(fde,dbg )          \
       
    55     do {                                               \
       
    56      if ((fde) == NULL) {                              \
       
    57         _dwarf_error(NULL, error, DW_DLE_FDE_NULL);    \
       
    58         return (DW_DLV_ERROR);                         \
       
    59     }                                                  \
       
    60     (dbg)= (fde)->fd_dbg;                              \
       
    61     if ((dbg) == NULL) {                               \
       
    62         _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);\
       
    63         return (DW_DLV_ERROR);                         \
       
    64     } } while (0)
       
    65 
       
    66 
       
    67 #define MIN(a,b)  (((a) < (b))? a:b)
       
    68 
       
    69 static void _dwarf_init_regrule_table(struct Dwarf_Reg_Rule_s *t1reg,
       
    70 				      int last_reg_num,
       
    71 				      int initial_value);
       
    72 static int dwarf_initialize_fde_table(Dwarf_Debug dbg,
       
    73 				      struct Dwarf_Frame_s *fde_table,
       
    74 				      unsigned table_real_data_size,
       
    75 				      Dwarf_Error * error);
       
    76 static void dwarf_free_fde_table(struct Dwarf_Frame_s *fde_table);
       
    77 
       
    78 #if 0
       
    79 /* Only used for debugging libdwarf. */
       
    80 static void dump_frame_rule(char *msg,
       
    81 			    struct Dwarf_Reg_Rule_s *reg_rule);
       
    82 #endif
       
    83 
       
    84 
       
    85 
       
    86 /* 
       
    87     This function is the heart of the debug_frame stuff.  Don't even
       
    88     think of reading this without reading both the Libdwarf and 
       
    89     consumer API carefully first.  This function basically executes     
       
    90     frame instructions contained in a Cie or an Fde, but does in a      
       
    91     number of different ways depending on the information sought.       
       
    92     Start_instr_ptr points to the first byte of the frame instruction    
       
    93     stream, and final_instr_ptr to the to the first byte after the       
       
    94     last.                                                                
       
    95                                                                         
       
    96     The offsets returned in the frame instructions are factored.  That   
       
    97     is they need to be multiplied by either the code_alignment_factor    
       
    98     or the data_alignment_factor, as appropriate to obtain the actual      
       
    99     offset.  This makes it possible to expand an instruction stream      
       
   100     without the corresponding Cie.  However, when an Fde frame instr     
       
   101     sequence is being expanded there must be a valid Cie with a pointer  
       
   102     to an initial table row.                                             
       
   103                                                                          
       
   104 
       
   105     If successful, returns DW_DLV_OK
       
   106 		And sets returned_count thru the pointer
       
   107 		 if make_instr is true.
       
   108 		If make_instr is false returned_count 
       
   109 		 should NOT be used by the caller (returned_count
       
   110 		 is set to 0 thru the pointer by this routine...)
       
   111     If unsuccessful, returns DW_DLV_ERROR
       
   112 		and sets returned_error to the error code
       
   113 
       
   114     It does not do a whole lot of input validation being a private 
       
   115     function.  Please make sure inputs are valid.
       
   116                                                                         
       
   117     (1) If make_instr is true, it makes a list of pointers to              
       
   118     Dwarf_Frame_Op structures containing the frame instructions          
       
   119     executed.  A pointer to this list is returned in ret_frame_instr.    
       
   120     Make_instr is true only when a list of frame instructions is to be   
       
   121     returned.  In this case since we are not interested in the contents  
       
   122     of the table, the input Cie can be NULL.  This is the only case
       
   123     where the inpute Cie can be NULL.
       
   124 
       
   125     (2) If search_pc is true, frame instructions are executed till       
       
   126     either a location is reached that is greater than the search_pc_val
       
   127     provided, or all instructions are executed.  At this point the       
       
   128     last row of the table generated is returned in a structure.          
       
   129     A pointer to this structure is supplied in table.                    
       
   130                                                                     
       
   131     (3) This function is also used to create the initial table row       
       
   132     defined by a Cie.  In this case, the Dwarf_Cie pointer cie, is       
       
   133     NULL.  For an FDE, however, cie points to the associated Cie.        
       
   134 
       
   135     make_instr - make list of frame instr? 0/1
       
   136     ret_frame_instr -  Ptr to list of ptrs to frame instrs
       
   137     search_pc  - Search for a pc value?  0/1
       
   138      search_pc_val -  Search for this pc value
       
   139     initial_loc - Initial code location value.
       
   140     start_instr_ptr -   Ptr to start of frame instrs.
       
   141     final_instr_ptr -   Ptr just past frame instrs. 
       
   142     table       -     Ptr to struct with last row. 
       
   143     cie     -   Ptr to Cie used by the Fde.
       
   144 
       
   145 */
       
   146 
       
   147 int
       
   148 _dwarf_exec_frame_instr(Dwarf_Bool make_instr,
       
   149 			Dwarf_Frame_Op ** ret_frame_instr,
       
   150 			Dwarf_Bool search_pc,
       
   151 			Dwarf_Addr search_pc_val,
       
   152 			Dwarf_Addr initial_loc,
       
   153 			Dwarf_Small * start_instr_ptr,
       
   154 			Dwarf_Small * final_instr_ptr,
       
   155 			Dwarf_Frame table,
       
   156 			Dwarf_Cie cie,
       
   157 			Dwarf_Debug dbg,
       
   158 			Dwarf_Half reg_num_of_cfa,
       
   159 			Dwarf_Sword * returned_count,
       
   160 			int *returned_error)
       
   161 {
       
   162 #define ERROR_IF_REG_NUM_TOO_HIGH(macreg,machigh_reg)               \
       
   163      do {                                             \
       
   164        if ((macreg) >= (machigh_reg) || (macreg) < 0) {            \
       
   165 	SIMPLE_ERROR_RETURN(DW_DLE_DF_REG_NUM_TOO_HIGH); \
       
   166        }                                              \
       
   167      } /*CONSTCOND */ while(0)
       
   168 #define SIMPLE_ERROR_RETURN(code) \
       
   169         free(localregtab); \
       
   170         *returned_error = code; \
       
   171         return DW_DLV_ERROR
       
   172 
       
   173     /* Sweeps the frame instructions. */
       
   174     Dwarf_Small *instr_ptr;
       
   175 
       
   176     /* Register numbers not limited to just 255, thus not using
       
   177        Dwarf_Small. */
       
   178     typedef int reg_num_type;
       
   179 
       
   180     Dwarf_Unsigned factored_N_value;
       
   181     Dwarf_Signed signed_factored_N_value;
       
   182     Dwarf_Addr current_loc = initial_loc;	/* code location/
       
   183 						   pc-value
       
   184 						   corresponding to the 
       
   185 						   frame instructions.
       
   186 						   Starts at zero when
       
   187 						   the caller has no
       
   188 						   value to pass in. */
       
   189 
       
   190     /* Must be min de_pointer_size bytes and must be at least sizeof
       
   191        Dwarf_ufixed */
       
   192     Dwarf_Unsigned adv_loc;
       
   193 
       
   194     int reg_count = dbg->de_frame_reg_rules_entry_count;
       
   195     struct Dwarf_Reg_Rule_s *localregtab = calloc(reg_count,
       
   196 					  sizeof(struct
       
   197 						 Dwarf_Reg_Rule_s));
       
   198 
       
   199     struct Dwarf_Reg_Rule_s cfa_reg;
       
   200 
       
   201 
       
   202     /* This is used to end executing frame instructions.  */
       
   203     /* Becomes true when search_pc is true and current_loc */
       
   204     /* is greater than search_pc_val.  */
       
   205     Dwarf_Bool search_over = false;
       
   206 
       
   207     /* Used by the DW_FRAME_advance_loc instr */
       
   208     /* to hold the increment in pc value.  */
       
   209     Dwarf_Addr adv_pc;
       
   210 
       
   211     /* Contains the length in bytes of */
       
   212     /* an leb128 encoded number.  */
       
   213     Dwarf_Word leb128_length;
       
   214 
       
   215     /* Counts the number of frame instructions executed.  */
       
   216     Dwarf_Word instr_count = 0;
       
   217 
       
   218     /* 
       
   219        These contain the current fields of the current frame
       
   220        instruction. */
       
   221     Dwarf_Small fp_base_op = 0;
       
   222     Dwarf_Small fp_extended_op;
       
   223     reg_num_type fp_register;
       
   224 
       
   225     /* The value in fp_offset may be signed, though we call it
       
   226        unsigned. This works ok for 2-s complement arithmetic. */
       
   227     Dwarf_Unsigned fp_offset;
       
   228     Dwarf_Off fp_instr_offset;
       
   229 
       
   230     /* 
       
   231        Stack_table points to the row (Dwarf_Frame ie) being pushed or
       
   232        popped by a remember or restore instruction. Top_stack points to 
       
   233        the top of the stack of rows. */
       
   234     Dwarf_Frame stack_table;
       
   235     Dwarf_Frame top_stack = NULL;
       
   236 
       
   237     /* 
       
   238        These are used only when make_instr is true. Curr_instr is a
       
   239        pointer to the current frame instruction executed.
       
   240        Curr_instr_ptr, head_instr_list, and curr_instr_list are used to 
       
   241        form a chain of Dwarf_Frame_Op structs. Dealloc_instr_ptr is
       
   242        used to deallocate the structs used to form the chain.
       
   243        Head_instr_block points to a contiguous list of pointers to the
       
   244        Dwarf_Frame_Op structs executed. */
       
   245     Dwarf_Frame_Op *curr_instr;
       
   246     Dwarf_Chain curr_instr_item, dealloc_instr_item;
       
   247     Dwarf_Chain head_instr_chain = NULL;
       
   248     Dwarf_Chain tail_instr_chain = NULL;
       
   249     Dwarf_Frame_Op *head_instr_block;
       
   250 
       
   251     /* 
       
   252        These are the alignment_factors taken from the Cie provided.
       
   253        When no input Cie is provided they are set to 1, because only
       
   254        factored offsets are required. */
       
   255     Dwarf_Sword code_alignment_factor = 1;
       
   256     Dwarf_Sword data_alignment_factor = 1;
       
   257 
       
   258     /* 
       
   259        This flag indicates when an actual alignment factor is needed.
       
   260        So if a frame instruction that computes an offset using an
       
   261        alignment factor is encountered when this flag is set, an error
       
   262        is returned because the Cie did not have a valid augmentation. */
       
   263     Dwarf_Bool need_augmentation = false;
       
   264 
       
   265     Dwarf_Word i;
       
   266 
       
   267     /* Initialize first row from associated Cie. Using temp regs
       
   268        explicity */
       
   269 
       
   270 
       
   271     if (localregtab == 0) {
       
   272 	SIMPLE_ERROR_RETURN(DW_DLE_ALLOC_FAIL);
       
   273     }
       
   274     {
       
   275 	struct Dwarf_Reg_Rule_s *t1reg = localregtab;
       
   276 	struct Dwarf_Reg_Rule_s *t1end = t1reg + reg_count;
       
   277 
       
   278 	if (cie != NULL && cie->ci_initial_table != NULL) {
       
   279 	    struct Dwarf_Reg_Rule_s *t2reg =
       
   280 		cie->ci_initial_table->fr_reg;
       
   281 
       
   282 	    if (reg_count != cie->ci_initial_table->fr_reg_count) {
       
   283 		/* Should never happen, it makes no sense to have the
       
   284 		   table sizes change. There is no real allowance for
       
   285 		   the set of registers to change dynamically in a
       
   286 		   single Dwarf_Debug (except the size can be set near
       
   287 		   initial Dwarf_Debug creation time). */
       
   288 		SIMPLE_ERROR_RETURN
       
   289 		    (DW_DLE_FRAME_REGISTER_COUNT_MISMATCH);
       
   290 	    }
       
   291 
       
   292 	    for (; t1reg < t1end; t1reg++, t2reg++) {
       
   293 		*t1reg = *t2reg;
       
   294 	    }
       
   295 	    cfa_reg = cie->ci_initial_table->fr_cfa_rule;
       
   296 	} else {
       
   297 	    _dwarf_init_regrule_table(t1reg,
       
   298 				      reg_count,
       
   299 				      dbg->de_frame_rule_initial_value);
       
   300 	    _dwarf_init_regrule_table(&cfa_reg, 1,
       
   301 				      dbg->de_frame_rule_initial_value);
       
   302 	}
       
   303     }
       
   304 
       
   305     /* 
       
   306        The idea here is that the code_alignment_factor and
       
   307        data_alignment_factor which are needed for certain instructions
       
   308        are valid only when the Cie has a proper augmentation string. So 
       
   309        if the augmentation is not right, only Frame instruction can be
       
   310        read. */
       
   311     if (cie != NULL && cie->ci_augmentation != NULL) {
       
   312 	code_alignment_factor = cie->ci_code_alignment_factor;
       
   313 	data_alignment_factor = cie->ci_data_alignment_factor;
       
   314     } else {
       
   315 	need_augmentation = !make_instr;
       
   316     }
       
   317 
       
   318     instr_ptr = start_instr_ptr;
       
   319     while ((instr_ptr < final_instr_ptr) && (!search_over)) {
       
   320         Dwarf_Small instr = 0;
       
   321         Dwarf_Small opcode = 0;
       
   322         reg_num_type reg_no = 0;
       
   323 
       
   324 
       
   325 	fp_instr_offset = instr_ptr - start_instr_ptr;
       
   326 	instr = *(Dwarf_Small *) instr_ptr;
       
   327 	instr_ptr += sizeof(Dwarf_Small);
       
   328 
       
   329 	fp_base_op = (instr & 0xc0) >> 6;
       
   330 	if ((instr & 0xc0) == 0x00) {
       
   331 	    opcode = instr;	/* is really extended op */
       
   332 	    fp_extended_op = (instr & (~(0xc0))) & 0xff;
       
   333 	} else {
       
   334 	    opcode = instr & 0xc0;	/* is base op */
       
   335 	    fp_extended_op = 0;
       
   336 	}
       
   337 
       
   338 	fp_register = 0;
       
   339 	fp_offset = 0;
       
   340 	switch (opcode) {
       
   341 	case DW_CFA_advance_loc:
       
   342 	    {
       
   343 		/* base op */
       
   344 		fp_offset = adv_pc = instr & DW_FRAME_INSTR_OFFSET_MASK;
       
   345 
       
   346 		if (need_augmentation) {
       
   347 		    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
       
   348 		}
       
   349 		adv_pc = adv_pc * code_alignment_factor;
       
   350 
       
   351 		search_over = search_pc &&
       
   352 		    (current_loc + adv_pc > search_pc_val);
       
   353 		/* If gone past pc needed, retain old pc.  */
       
   354 		if (!search_over)
       
   355 		    current_loc = current_loc + adv_pc;
       
   356 		break;
       
   357 	    }
       
   358 
       
   359 	case DW_CFA_offset:
       
   360 	    {			/* base op */
       
   361 		reg_no =
       
   362 		    (reg_num_type) (instr & DW_FRAME_INSTR_OFFSET_MASK);
       
   363 		ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
       
   364 
       
   365 		factored_N_value =
       
   366 		    _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
       
   367 		instr_ptr = instr_ptr + leb128_length;
       
   368 
       
   369 		fp_register = reg_no;
       
   370 		fp_offset = factored_N_value;
       
   371 
       
   372 		if (need_augmentation) {
       
   373 		    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
       
   374 		}
       
   375 
       
   376 		localregtab[reg_no].ru_is_off = 1;
       
   377 		localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET;
       
   378 		localregtab[reg_no].ru_register = reg_num_of_cfa;
       
   379 		localregtab[reg_no].ru_offset_or_block_len =
       
   380 		    factored_N_value * data_alignment_factor;
       
   381 
       
   382 		break;
       
   383 	    }
       
   384 
       
   385 	case DW_CFA_restore:
       
   386 	    {			/* base op */
       
   387 		reg_no = (instr & DW_FRAME_INSTR_OFFSET_MASK);
       
   388 		ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
       
   389 
       
   390 		fp_register = reg_no;
       
   391 
       
   392 		if (cie != NULL && cie->ci_initial_table != NULL)
       
   393 		    localregtab[reg_no] = 
       
   394                        cie->ci_initial_table->fr_reg[reg_no];
       
   395 		else if (!make_instr) {
       
   396 		    SIMPLE_ERROR_RETURN(DW_DLE_DF_MAKE_INSTR_NO_INIT);
       
   397 		}
       
   398 
       
   399 		break;
       
   400 	    }
       
   401 	case DW_CFA_set_loc:
       
   402 	    {
       
   403 		Dwarf_Addr new_loc = 0;
       
   404 
       
   405 		READ_UNALIGNED(dbg, new_loc, Dwarf_Addr,
       
   406 			       instr_ptr, dbg->de_pointer_size);
       
   407 		instr_ptr += dbg->de_pointer_size;
       
   408 		if (new_loc != 0 && current_loc != 0) {
       
   409 		    /* Pre-relocation or before current_loc is set the
       
   410 		       test comparing new_loc and current_loc makes no
       
   411 		       sense. Testing for non-zero (above) is a way
       
   412 		       (fallible) to check that current_loc, new_loc
       
   413 		       are already relocated.  */
       
   414 		    if (new_loc <= current_loc) {
       
   415 			/* Within a frame, address must increase.
       
   416 			   Seemingly it has not. Seems to be an error. */
       
   417 
       
   418 			SIMPLE_ERROR_RETURN
       
   419 			    (DW_DLE_DF_NEW_LOC_LESS_OLD_LOC);
       
   420 		    }
       
   421 		}
       
   422 
       
   423 		search_over = search_pc && (new_loc > search_pc_val);
       
   424 
       
   425 		/* If gone past pc needed, retain old pc.  */
       
   426 		if (!search_over)
       
   427 		    current_loc = new_loc;
       
   428 		fp_offset = new_loc;
       
   429 		break;
       
   430 	    }
       
   431 
       
   432 	case DW_CFA_advance_loc1:
       
   433 	    {
       
   434 		fp_offset = adv_loc = *(Dwarf_Small *) instr_ptr;
       
   435 		instr_ptr += sizeof(Dwarf_Small);
       
   436 
       
   437 		if (need_augmentation) {
       
   438 		    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
       
   439 		}
       
   440 		adv_loc *= code_alignment_factor;
       
   441 
       
   442 		search_over = search_pc &&
       
   443 		    (current_loc + adv_loc > search_pc_val);
       
   444 
       
   445 		/* If gone past pc needed, retain old pc.  */
       
   446 		if (!search_over)
       
   447 		    current_loc = current_loc + adv_loc;
       
   448 		break;
       
   449 	    }
       
   450 
       
   451 	case DW_CFA_advance_loc2:
       
   452 	    {
       
   453 		READ_UNALIGNED(dbg, adv_loc, Dwarf_Unsigned,
       
   454 			       instr_ptr, sizeof(Dwarf_Half));
       
   455 		instr_ptr += sizeof(Dwarf_Half);
       
   456 		fp_offset = adv_loc;
       
   457 
       
   458 		if (need_augmentation) {
       
   459 		    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
       
   460 		}
       
   461 		adv_loc *= code_alignment_factor;
       
   462 
       
   463 		search_over = search_pc &&
       
   464 		    (current_loc + adv_loc > search_pc_val);
       
   465 
       
   466 		/* If gone past pc needed, retain old pc.  */
       
   467 		if (!search_over)
       
   468 		    current_loc = current_loc + adv_loc;
       
   469 		break;
       
   470 	    }
       
   471 
       
   472 	case DW_CFA_advance_loc4:
       
   473 	    {
       
   474 		READ_UNALIGNED(dbg, adv_loc, Dwarf_Unsigned,
       
   475 			       instr_ptr, sizeof(Dwarf_ufixed));
       
   476 		instr_ptr += sizeof(Dwarf_ufixed);
       
   477 		fp_offset = adv_loc;
       
   478 
       
   479 		if (need_augmentation) {
       
   480 		    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
       
   481 		}
       
   482 		adv_loc *= code_alignment_factor;
       
   483 
       
   484 		search_over = search_pc &&
       
   485 		    (current_loc + adv_loc > search_pc_val);
       
   486 
       
   487 		/* If gone past pc needed, retain old pc.  */
       
   488 		if (!search_over)
       
   489 		    current_loc = current_loc + adv_loc;
       
   490 		break;
       
   491 	    }
       
   492 
       
   493 	case DW_CFA_offset_extended:
       
   494 	    {
       
   495 		Dwarf_Unsigned lreg;
       
   496 
       
   497 		DECODE_LEB128_UWORD(instr_ptr, lreg);
       
   498 		reg_no = (reg_num_type) lreg;
       
   499 		ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);;
       
   500 		factored_N_value =
       
   501 		    _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
       
   502 		instr_ptr += leb128_length;
       
   503 
       
   504 		if (need_augmentation) {
       
   505 		    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
       
   506 		}
       
   507 		localregtab[reg_no].ru_is_off = 1;
       
   508 		localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET;
       
   509 		localregtab[reg_no].ru_register = reg_num_of_cfa;
       
   510 		localregtab[reg_no].ru_offset_or_block_len = factored_N_value *
       
   511 		    data_alignment_factor;
       
   512 
       
   513 		fp_register = reg_no;
       
   514 		fp_offset = factored_N_value;
       
   515 		break;
       
   516 	    }
       
   517 
       
   518 	case DW_CFA_restore_extended:
       
   519 	    {
       
   520 		Dwarf_Unsigned lreg;
       
   521 
       
   522 		DECODE_LEB128_UWORD(instr_ptr, lreg);
       
   523 		reg_no = (reg_num_type) lreg;
       
   524 
       
   525 		ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
       
   526 
       
   527 		if (cie != NULL && cie->ci_initial_table != NULL) {
       
   528 		    localregtab[reg_no] = cie->ci_initial_table->fr_reg[reg_no];
       
   529 		} else {
       
   530 		    if (!make_instr) {
       
   531 			SIMPLE_ERROR_RETURN
       
   532 			    (DW_DLE_DF_MAKE_INSTR_NO_INIT);
       
   533 		    }
       
   534 		}
       
   535 
       
   536 		fp_register = reg_no;
       
   537 		break;
       
   538 	    }
       
   539 
       
   540 	case DW_CFA_undefined:
       
   541 	    {
       
   542 		Dwarf_Unsigned lreg;
       
   543 
       
   544 		DECODE_LEB128_UWORD(instr_ptr, lreg);
       
   545 		reg_no = (reg_num_type) lreg;
       
   546 		ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
       
   547 
       
   548 		localregtab[reg_no].ru_is_off = 0;
       
   549 		localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET;
       
   550 		localregtab[reg_no].ru_register = DW_FRAME_UNDEFINED_VAL;
       
   551 		localregtab[reg_no].ru_offset_or_block_len = 0;
       
   552 
       
   553 		fp_register = reg_no;
       
   554 		break;
       
   555 	    }
       
   556 
       
   557 	case DW_CFA_same_value:
       
   558 	    {
       
   559 		Dwarf_Unsigned lreg;
       
   560 
       
   561 		DECODE_LEB128_UWORD(instr_ptr, lreg);
       
   562 		reg_no = (reg_num_type) lreg;
       
   563 		ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
       
   564 
       
   565 		localregtab[reg_no].ru_is_off = 0;
       
   566 		localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET;
       
   567 		localregtab[reg_no].ru_register = DW_FRAME_SAME_VAL;
       
   568 		localregtab[reg_no].ru_offset_or_block_len = 0;
       
   569 		fp_register = reg_no;
       
   570 		break;
       
   571 	    }
       
   572 
       
   573 	case DW_CFA_register:
       
   574 	    {
       
   575 		Dwarf_Unsigned lreg;
       
   576 		reg_num_type reg_noA = 0;
       
   577 		reg_num_type reg_noB = 0;
       
   578 
       
   579 		DECODE_LEB128_UWORD(instr_ptr, lreg);
       
   580 		reg_noA = (reg_num_type) lreg;
       
   581 
       
   582 		ERROR_IF_REG_NUM_TOO_HIGH(reg_noA, reg_count);
       
   583 
       
   584 		DECODE_LEB128_UWORD(instr_ptr, lreg);
       
   585 		reg_noB = (reg_num_type) lreg;
       
   586 
       
   587 		if (reg_noB > reg_count) {
       
   588 		    SIMPLE_ERROR_RETURN(DW_DLE_DF_REG_NUM_TOO_HIGH);
       
   589 		}
       
   590 
       
   591 
       
   592 		localregtab[reg_noA].ru_is_off = 0;
       
   593 		localregtab[reg_noA].ru_value_type = DW_EXPR_OFFSET;
       
   594 		localregtab[reg_noA].ru_register = reg_noB;
       
   595 		localregtab[reg_noA].ru_offset_or_block_len = 0;
       
   596 
       
   597 		fp_register = reg_noA;
       
   598 		fp_offset = reg_noB;
       
   599 		break;
       
   600 	    }
       
   601 
       
   602 	case DW_CFA_remember_state:
       
   603 	    {
       
   604 		stack_table = (Dwarf_Frame)
       
   605 		    _dwarf_get_alloc(dbg, DW_DLA_FRAME, 1);
       
   606 		if (stack_table == NULL) {
       
   607 		    SIMPLE_ERROR_RETURN(DW_DLE_DF_ALLOC_FAIL);
       
   608 		}
       
   609 
       
   610 		for (i = 0; i < reg_count; i++)
       
   611 		    stack_table->fr_reg[i] = localregtab[i];
       
   612 
       
   613 		if (top_stack != NULL)
       
   614 		    stack_table->fr_next = top_stack;
       
   615 		top_stack = stack_table;
       
   616 
       
   617 		break;
       
   618 	    }
       
   619 
       
   620 	case DW_CFA_restore_state:
       
   621 	    {
       
   622 		if (top_stack == NULL) {
       
   623 		    SIMPLE_ERROR_RETURN(DW_DLE_DF_POP_EMPTY_STACK);
       
   624 		}
       
   625 		stack_table = top_stack;
       
   626 		top_stack = stack_table->fr_next;
       
   627 
       
   628 		for (i = 0; i < reg_count; i++)
       
   629 		    localregtab[i] = stack_table->fr_reg[i];
       
   630 
       
   631 		dwarf_dealloc(dbg, stack_table, DW_DLA_FRAME);
       
   632 		break;
       
   633 	    }
       
   634 
       
   635 	case DW_CFA_def_cfa:
       
   636 	    {
       
   637 		Dwarf_Unsigned lreg;
       
   638 
       
   639 		DECODE_LEB128_UWORD(instr_ptr, lreg);
       
   640 		reg_no = (reg_num_type) lreg;
       
   641 
       
   642 		ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
       
   643 
       
   644 		factored_N_value =
       
   645 		    _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
       
   646 		instr_ptr += leb128_length;
       
   647 
       
   648 		if (need_augmentation) {
       
   649 		    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
       
   650 		}
       
   651 		cfa_reg.ru_is_off = 1;
       
   652 		cfa_reg.ru_value_type = DW_EXPR_OFFSET;
       
   653 		cfa_reg.ru_register = reg_no;
       
   654 		cfa_reg.ru_offset_or_block_len = factored_N_value;
       
   655 
       
   656 		fp_register = reg_no;
       
   657 		fp_offset = factored_N_value;
       
   658 		break;
       
   659 	    }
       
   660 
       
   661 	case DW_CFA_def_cfa_register:
       
   662 	    {
       
   663 		Dwarf_Unsigned lreg;
       
   664 
       
   665 		DECODE_LEB128_UWORD(instr_ptr, lreg);
       
   666 		reg_no = (reg_num_type) lreg;
       
   667 		ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
       
   668 
       
   669 		cfa_reg.ru_register = reg_no;
       
   670 		/* Do NOT set ru_offset_or_block_len or ru_is_off here. 
       
   671 		   See dwarf2/3 spec.  */
       
   672 		fp_register = reg_no;
       
   673 		break;
       
   674 	    }
       
   675 
       
   676 	case DW_CFA_def_cfa_offset:
       
   677 	    {
       
   678 		factored_N_value =
       
   679 		    _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
       
   680 		instr_ptr += leb128_length;
       
   681 
       
   682 		if (need_augmentation) {
       
   683 		    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
       
   684 		}
       
   685 		/* Do set ru_is_off here, as here factored_N_value
       
   686 		   counts.  */
       
   687 		cfa_reg.ru_is_off = 1;
       
   688 		cfa_reg.ru_value_type = DW_EXPR_OFFSET;
       
   689 		cfa_reg.ru_offset_or_block_len = factored_N_value;
       
   690 
       
   691 		fp_offset = factored_N_value;
       
   692 		break;
       
   693 	    }
       
   694 	case DW_CFA_nop:
       
   695 	    {
       
   696 		break;
       
   697 	    }
       
   698 	    /* DWARF3 ops begin here. */
       
   699 	case DW_CFA_def_cfa_expression:
       
   700 	    {
       
   701 		/* A single DW_FORM_block representing a dwarf
       
   702 		   expression. The form block establishes the way to
       
   703 		   compute the CFA. */
       
   704 		Dwarf_Unsigned block_len = 0;
       
   705 
       
   706 		DECODE_LEB128_UWORD(instr_ptr, block_len);
       
   707 		cfa_reg.ru_is_off = 0;	/* arbitrary */
       
   708 		cfa_reg.ru_value_type = DW_EXPR_EXPRESSION;
       
   709 		cfa_reg.ru_offset_or_block_len = block_len;
       
   710 		cfa_reg.ru_block = instr_ptr;
       
   711 		fp_offset = (Dwarf_Unsigned) instr_ptr;
       
   712 
       
   713 	    }
       
   714 	    break;
       
   715 	case DW_CFA_expression:
       
   716 	    {
       
   717 		/* An unsigned leb128 value is the first operand (a
       
   718 		   register number). The second operand is single
       
   719 		   DW_FORM_block representing a dwarf expression. The
       
   720 		   evaluator pushes the CFA on the evaluation stack
       
   721 		   then evaluates the expression to compute the value
       
   722 		   of the register contents. */
       
   723 		Dwarf_Unsigned lreg = 0;
       
   724 		Dwarf_Unsigned block_len = 0;
       
   725 
       
   726 		DECODE_LEB128_UWORD(instr_ptr, lreg);
       
   727 		reg_no = (reg_num_type) lreg;
       
   728 		ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
       
   729 		DECODE_LEB128_UWORD(instr_ptr, block_len);
       
   730 		localregtab[lreg].ru_is_off = 0;	/* arbitrary */
       
   731 		localregtab[lreg].ru_value_type = DW_EXPR_EXPRESSION;
       
   732 		localregtab[lreg].ru_offset_or_block_len = block_len;
       
   733 		localregtab[lreg].ru_block = instr_ptr;
       
   734 		fp_offset = (Dwarf_Unsigned) instr_ptr;
       
   735 		fp_register = reg_no;
       
   736 
       
   737 	    }
       
   738 	    break;
       
   739 	case DW_CFA_cfa_offset_extended_sf:
       
   740 	    {
       
   741 		/* The first operand is an unsigned leb128 register
       
   742 		   number. The second is a signed factored offset.
       
   743 		   Identical to DW_CFA_offset_extended except the
       
   744 		   secondoperand is signed */
       
   745 		Dwarf_Unsigned lreg;
       
   746 
       
   747 		DECODE_LEB128_UWORD(instr_ptr, lreg);
       
   748 		reg_no = (reg_num_type) lreg;
       
   749 		ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
       
   750 		signed_factored_N_value =
       
   751 		    _dwarf_decode_s_leb128(instr_ptr, &leb128_length);
       
   752 		instr_ptr += leb128_length;
       
   753 
       
   754 		if (need_augmentation) {
       
   755 		    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
       
   756 		}
       
   757 		localregtab[reg_no].ru_is_off = 1;
       
   758 		localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET;
       
   759 		localregtab[reg_no].ru_register = reg_num_of_cfa;
       
   760 		localregtab[reg_no].ru_offset_or_block_len =
       
   761 		    signed_factored_N_value * data_alignment_factor;
       
   762 
       
   763 		fp_register = reg_no;
       
   764 		fp_offset = signed_factored_N_value;
       
   765 	    }
       
   766 	    break;
       
   767 	case DW_CFA_def_cfa_sf:
       
   768 	    {
       
   769 		/* The first operand is an unsigned leb128 register
       
   770 		   number. The second is a signed leb128 factored
       
   771 		   offset. Identical to DW_CFA_def_cfa except that the
       
   772 		   second operand is signed and factored. */
       
   773 		Dwarf_Unsigned lreg;
       
   774 
       
   775 		DECODE_LEB128_UWORD(instr_ptr, lreg);
       
   776 		reg_no = (reg_num_type) lreg;
       
   777 		ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
       
   778 
       
   779 		signed_factored_N_value =
       
   780 		    _dwarf_decode_s_leb128(instr_ptr, &leb128_length);
       
   781 		instr_ptr += leb128_length;
       
   782 
       
   783 		if (need_augmentation) {
       
   784 		    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
       
   785 		}
       
   786 		cfa_reg.ru_is_off = 1;
       
   787 		cfa_reg.ru_value_type = DW_EXPR_OFFSET;
       
   788 		cfa_reg.ru_register = reg_no;
       
   789 		cfa_reg.ru_offset_or_block_len =
       
   790 		    signed_factored_N_value * data_alignment_factor;
       
   791 
       
   792 		fp_register = reg_no;
       
   793 		fp_offset = signed_factored_N_value;
       
   794 	    }
       
   795 	    break;
       
   796 	case DW_CFA_def_cfa_offset_sf:
       
   797 	    {
       
   798 		/* The operand is a signed leb128 operand representing
       
   799 		   a factored offset.  Identical to
       
   800 		   DW_CFA_def_cfa_offset excep the operand is signed
       
   801 		   and factored. */
       
   802 
       
   803 		signed_factored_N_value =
       
   804 		    _dwarf_decode_s_leb128(instr_ptr, &leb128_length);
       
   805 		instr_ptr += leb128_length;
       
   806 
       
   807 		if (need_augmentation) {
       
   808 		    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
       
   809 		}
       
   810 		/* Do set ru_is_off here, as here factored_N_value
       
   811 		   counts.  */
       
   812 		cfa_reg.ru_is_off = 1;
       
   813 		cfa_reg.ru_value_type = DW_EXPR_OFFSET;
       
   814 		cfa_reg.ru_offset_or_block_len =
       
   815 		    signed_factored_N_value * data_alignment_factor;
       
   816 
       
   817 		fp_offset = signed_factored_N_value;
       
   818 	    }
       
   819 	    break;
       
   820 	case DW_CFA_val_offset:
       
   821 	    {
       
   822 		/* The first operand is an unsigned leb128 register
       
   823 		   number. The second is a factored unsigned offset.
       
   824 		   Makes the register be a val_offset(N) rule with N =
       
   825 		   factored_offset*data_alignment_factor. */
       
   826 
       
   827 		Dwarf_Unsigned lreg;
       
   828 
       
   829 		DECODE_LEB128_UWORD(instr_ptr, lreg);
       
   830 		reg_no = (reg_num_type) lreg;
       
   831 
       
   832 		ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
       
   833 
       
   834 		factored_N_value =
       
   835 		    _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
       
   836 		instr_ptr += leb128_length;
       
   837 
       
   838 		if (need_augmentation) {
       
   839 		    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
       
   840 		}
       
   841 		/* Do set ru_is_off here, as here factored_N_value
       
   842 		   counts.  */
       
   843 		localregtab[reg_no].ru_is_off = 1;
       
   844 		localregtab[reg_no].ru_register = reg_num_of_cfa;
       
   845 		localregtab[reg_no].ru_value_type = DW_EXPR_VAL_OFFSET;
       
   846 		localregtab[reg_no].ru_offset_or_block_len =
       
   847 		    factored_N_value * data_alignment_factor;
       
   848 
       
   849 		fp_offset = factored_N_value;
       
   850 		break;
       
   851 	    }
       
   852 	case DW_CFA_val_offset_sf:
       
   853 	    {
       
   854 		/* The first operand is an unsigned leb128 register
       
   855 		   number. The second is a factored signed offset.
       
   856 		   Makes the register be a val_offset(N) rule with N =
       
   857 		   factored_offset*data_alignment_factor. */
       
   858 		Dwarf_Unsigned lreg;
       
   859 
       
   860 		DECODE_LEB128_UWORD(instr_ptr, lreg);
       
   861 		reg_no = (reg_num_type) lreg;
       
   862 
       
   863 		ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
       
   864 		signed_factored_N_value =
       
   865 		    _dwarf_decode_s_leb128(instr_ptr, &leb128_length);
       
   866 		instr_ptr += leb128_length;
       
   867 
       
   868 		if (need_augmentation) {
       
   869 		    SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
       
   870 		}
       
   871 		/* Do set ru_is_off here, as here factored_N_value
       
   872 		   counts.  */
       
   873 		localregtab[reg_no].ru_is_off = 1;
       
   874 		localregtab[reg_no].ru_value_type = DW_EXPR_VAL_OFFSET;
       
   875 		localregtab[reg_no].ru_offset_or_block_len =
       
   876 		    signed_factored_N_value * data_alignment_factor;
       
   877 
       
   878 		fp_offset = signed_factored_N_value;
       
   879 
       
   880 	    }
       
   881 	    break;
       
   882 	case DW_CFA_val_expression:
       
   883 	    {
       
   884 		/* The first operand is an unsigned leb128 register
       
   885 		   number. The second is a DW_FORM_block representing a 
       
   886 		   DWARF expression. The rule for the register number
       
   887 		   becomes a val_expression(E) rule. */
       
   888 		Dwarf_Unsigned lreg = 0;
       
   889 		Dwarf_Unsigned block_len = 0;
       
   890 
       
   891 		DECODE_LEB128_UWORD(instr_ptr, lreg);
       
   892 		reg_no = (reg_num_type) lreg;
       
   893 		ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
       
   894 		DECODE_LEB128_UWORD(instr_ptr, block_len);
       
   895 		localregtab[lreg].ru_is_off = 0;	/* arbitrary */
       
   896 		localregtab[lreg].ru_value_type = DW_EXPR_VAL_EXPRESSION;
       
   897 		localregtab[lreg].ru_offset_or_block_len = block_len;
       
   898 		localregtab[lreg].ru_block = instr_ptr;
       
   899 		fp_offset = (Dwarf_Unsigned) instr_ptr;
       
   900 
       
   901                 instr_ptr += block_len;
       
   902 		fp_register = reg_no;
       
   903 
       
   904 	    }
       
   905 	    break;
       
   906 
       
   907 	    /* END DWARF3 new ops. */
       
   908 
       
   909 
       
   910 #ifdef DW_CFA_GNU_window_save
       
   911 	case DW_CFA_GNU_window_save:
       
   912 	    {
       
   913 		/* no information: this just tells unwinder to restore
       
   914 		   the window registers from the previous frame's
       
   915 		   window save area */
       
   916 		break;
       
   917 	    }
       
   918 #endif
       
   919 #ifdef  DW_CFA_GNU_args_size
       
   920 	    /* single uleb128 is the current arg area size in bytes. No 
       
   921 	       register exists yet to save this in */
       
   922 	case DW_CFA_GNU_args_size:
       
   923 	    {
       
   924 		Dwarf_Unsigned lreg;
       
   925 
       
   926 		DECODE_LEB128_UWORD(instr_ptr, lreg);
       
   927 		reg_no = (reg_num_type) lreg;
       
   928 
       
   929 		break;
       
   930 	    }
       
   931 #endif
       
   932 	default:
       
   933 	    /* ERROR, we have an opcode we know nothing about. Memory
       
   934 	       leak here, but an error like this is not supposed to
       
   935 	       happen so we ignore the leak. These used to be ignored,
       
   936 	       now we notice and report. */
       
   937 	    SIMPLE_ERROR_RETURN(DW_DLE_DF_FRAME_DECODING_ERROR);
       
   938 
       
   939 	}
       
   940 
       
   941 	if (make_instr) {
       
   942 	    instr_count++;
       
   943 
       
   944 	    curr_instr = (Dwarf_Frame_Op *)
       
   945 		_dwarf_get_alloc(dbg, DW_DLA_FRAME_OP, 1);
       
   946 	    if (curr_instr == NULL) {
       
   947 		SIMPLE_ERROR_RETURN(DW_DLE_DF_ALLOC_FAIL);
       
   948 	    }
       
   949 
       
   950 	    curr_instr->fp_base_op = fp_base_op;
       
   951 	    curr_instr->fp_extended_op = fp_extended_op;
       
   952 	    curr_instr->fp_register = fp_register;
       
   953 	    curr_instr->fp_offset = fp_offset;
       
   954 	    curr_instr->fp_instr_offset = fp_instr_offset;
       
   955 
       
   956 	    curr_instr_item = (Dwarf_Chain)
       
   957 		_dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
       
   958 	    if (curr_instr_item == NULL) {
       
   959 		SIMPLE_ERROR_RETURN(DW_DLE_DF_ALLOC_FAIL);
       
   960 	    }
       
   961 
       
   962 	    curr_instr_item->ch_item = curr_instr;
       
   963 	    if (head_instr_chain == NULL)
       
   964 		head_instr_chain = tail_instr_chain = curr_instr_item;
       
   965 	    else {
       
   966 		tail_instr_chain->ch_next = curr_instr_item;
       
   967 		tail_instr_chain = curr_instr_item;
       
   968 	    }
       
   969 	}
       
   970     }
       
   971 
       
   972     /* 
       
   973        If frame instruction decoding was right we would stop exactly at 
       
   974        final_instr_ptr. */
       
   975     if (instr_ptr > final_instr_ptr) {
       
   976 	SIMPLE_ERROR_RETURN(DW_DLE_DF_FRAME_DECODING_ERROR);
       
   977     }
       
   978 
       
   979     /* Create the last row generated.  */
       
   980     if (table != NULL) {
       
   981 
       
   982 	struct Dwarf_Reg_Rule_s *t2reg = table->fr_reg;
       
   983 	struct Dwarf_Reg_Rule_s *t3reg = localregtab;
       
   984 	struct Dwarf_Reg_Rule_s *t3end = t3reg + reg_count;
       
   985 
       
   986 	table->fr_loc = current_loc;
       
   987 	for (; t3reg < t3end; t3reg++, t2reg++) {
       
   988 	    *t2reg = *t3reg;
       
   989 	}
       
   990 
       
   991 	/* CONSTCOND */
       
   992 	if (reg_num_of_cfa < reg_count) {
       
   993 	    t2reg = table->fr_reg + reg_num_of_cfa;
       
   994 	    /* Update both the old DW_FRAME_CFA_COL row and the new
       
   995 	       fr_cfa_rule with the cfa_reg, this is the old-style
       
   996 	       update. */
       
   997 	    *t2reg = cfa_reg;
       
   998 	}
       
   999 	table->fr_cfa_rule = cfa_reg;
       
  1000     }
       
  1001 
       
  1002     /* Dealloc anything remaining on stack. */
       
  1003     for (; top_stack != NULL;) {
       
  1004 	stack_table = top_stack;
       
  1005 	top_stack = top_stack->fr_next;
       
  1006 	dwarf_dealloc(dbg, stack_table, DW_DLA_FRAME);
       
  1007     }
       
  1008 
       
  1009     if (make_instr) {
       
  1010 	/* Allocate list of pointers to Dwarf_Frame_Op's.  */
       
  1011 	head_instr_block = (Dwarf_Frame_Op *)
       
  1012 	    _dwarf_get_alloc(dbg, DW_DLA_FRAME_BLOCK, instr_count);
       
  1013 	if (head_instr_block == NULL) {
       
  1014 	    SIMPLE_ERROR_RETURN(DW_DLE_DF_ALLOC_FAIL);
       
  1015 	}
       
  1016 
       
  1017 	/* 
       
  1018 	   Store pointers to Dwarf_Frame_Op's in this list and
       
  1019 	   deallocate the structs that chain the Dwarf_Frame_Op's. */
       
  1020 	curr_instr_item = head_instr_chain;
       
  1021 	for (i = 0; i < instr_count; i++) {
       
  1022 	    *(head_instr_block + i) =
       
  1023 		*(Dwarf_Frame_Op *) curr_instr_item->ch_item;
       
  1024 	    dealloc_instr_item = curr_instr_item;
       
  1025 	    curr_instr_item = curr_instr_item->ch_next;
       
  1026 	    dwarf_dealloc(dbg, dealloc_instr_item->ch_item,
       
  1027 			  DW_DLA_FRAME_OP);
       
  1028 	    dwarf_dealloc(dbg, dealloc_instr_item, DW_DLA_CHAIN);
       
  1029 	}
       
  1030 	*ret_frame_instr = head_instr_block;
       
  1031 
       
  1032 	*returned_count = (Dwarf_Sword) instr_count;
       
  1033     } else {
       
  1034 	*returned_count = 0;
       
  1035     }
       
  1036     free(localregtab);
       
  1037     return DW_DLV_OK;
       
  1038 #undef ERROR_IF_REG_NUM_TOO_HIGH
       
  1039 #undef SIMPLE_ERROR_RETURN
       
  1040 }
       
  1041 
       
  1042 /*  Depending on version, either read the return address register
       
  1043     as a ubyte or as an leb number.
       
  1044     The form of this value changed for DWARF3.
       
  1045 */
       
  1046 Dwarf_Unsigned
       
  1047 _dwarf_get_return_address_reg(Dwarf_Small * frame_ptr,
       
  1048 			      int version, unsigned long *size)
       
  1049 {
       
  1050     Dwarf_Unsigned uvalue = 0;
       
  1051     Dwarf_Word leb128_length = 0;
       
  1052 
       
  1053     if (version == 1) {
       
  1054 	*size = 1;
       
  1055 	uvalue = *(unsigned char *) frame_ptr;
       
  1056 	return uvalue;
       
  1057     }
       
  1058     uvalue = _dwarf_decode_u_leb128(frame_ptr, &leb128_length);
       
  1059     *size = leb128_length;
       
  1060     return uvalue;
       
  1061 }
       
  1062 
       
  1063 
       
  1064 /* Trivial consumer function. 
       
  1065 */
       
  1066 int
       
  1067 dwarf_get_cie_of_fde(Dwarf_Fde fde,
       
  1068 		     Dwarf_Cie * cie_returned, Dwarf_Error * error)
       
  1069 {
       
  1070     if (fde == NULL) {
       
  1071 	_dwarf_error(NULL, error, DW_DLE_FDE_NULL);
       
  1072 	return (DW_DLV_ERROR);
       
  1073     }
       
  1074 
       
  1075     *cie_returned = fde->fd_cie;
       
  1076     return DW_DLV_OK;
       
  1077 
       
  1078 }
       
  1079 
       
  1080 /*
       
  1081   For g++ .eh_frame fde and cie.
       
  1082   the cie id is different as the
       
  1083   definition of the cie_id in an fde
       
  1084 	is the distance back from the address of the
       
  1085 	value to the cie.
       
  1086   Or 0 if this is a true cie.
       
  1087   Non standard dwarf, designed this way to be
       
  1088   convenient at run time for an allocated 
       
  1089   (mapped into memory as part of the running image) section.
       
  1090 */
       
  1091 int
       
  1092 dwarf_get_fde_list_eh(Dwarf_Debug dbg,
       
  1093 		      Dwarf_Cie ** cie_data,
       
  1094 		      Dwarf_Signed * cie_element_count,
       
  1095 		      Dwarf_Fde ** fde_data,
       
  1096 		      Dwarf_Signed * fde_element_count,
       
  1097 		      Dwarf_Error * error)
       
  1098 {
       
  1099     int res;
       
  1100 
       
  1101     res =
       
  1102 	_dwarf_load_section(dbg,
       
  1103 			    dbg->de_debug_frame_eh_gnu_index,
       
  1104 			    &dbg->de_debug_frame_eh_gnu, error);
       
  1105 
       
  1106     if (res != DW_DLV_OK) {
       
  1107 	return res;
       
  1108     }
       
  1109 
       
  1110     res =
       
  1111 	_dwarf_get_fde_list_internal(dbg,
       
  1112 				     cie_data,
       
  1113 				     cie_element_count,
       
  1114 				     fde_data,
       
  1115 				     fde_element_count,
       
  1116 				     dbg->de_debug_frame_eh_gnu,
       
  1117 				     dbg->de_debug_frame_eh_gnu_index,
       
  1118 				     dbg->de_debug_frame_size_eh_gnu,
       
  1119 				     /* cie_id_value */ 0,
       
  1120 				     /* use_gnu_cie_calc= */ 1,
       
  1121 				     error);
       
  1122     return res;
       
  1123 }
       
  1124 
       
  1125 
       
  1126 
       
  1127 /*
       
  1128   For standard dwarf .debug_frame
       
  1129   cie_id is -1  in a cie, and
       
  1130   is the section offset in the .debug_frame section
       
  1131   of the cie otherwise.  Standard dwarf
       
  1132 */
       
  1133 int
       
  1134 dwarf_get_fde_list(Dwarf_Debug dbg,
       
  1135 		   Dwarf_Cie ** cie_data,
       
  1136 		   Dwarf_Signed * cie_element_count,
       
  1137 		   Dwarf_Fde ** fde_data,
       
  1138 		   Dwarf_Signed * fde_element_count,
       
  1139 		   Dwarf_Error * error)
       
  1140 {
       
  1141     int res;
       
  1142 
       
  1143     res =
       
  1144 	_dwarf_load_section(dbg,
       
  1145 			    dbg->de_debug_frame_index,
       
  1146 			    &dbg->de_debug_frame, error);
       
  1147 
       
  1148     if (res != DW_DLV_OK) {
       
  1149 	return res;
       
  1150     }
       
  1151 
       
  1152     res =
       
  1153 	_dwarf_get_fde_list_internal(dbg, cie_data,
       
  1154 				     cie_element_count,
       
  1155 				     fde_data,
       
  1156 				     fde_element_count,
       
  1157 				     dbg->de_debug_frame,
       
  1158 				     dbg->de_debug_frame_index,
       
  1159 				     dbg->de_debug_frame_size,
       
  1160 				     DW_CIE_ID,
       
  1161 				     /* use_gnu_cie_calc= */ 0,
       
  1162 				     error);
       
  1163 
       
  1164     return res;
       
  1165 }
       
  1166 
       
  1167 
       
  1168 /*
       
  1169    Only works on dwarf sections, not eh_frame
       
  1170    Given a Dwarf_Die, see if it has a
       
  1171    DW_AT_MIPS_fde attribute and if so use that
       
  1172    to get an fde offset.
       
  1173    Then create a Dwarf_Fde to return thru the ret_fde pointer.
       
  1174    Also creates a cie (pointed at from the Dwarf_Fde).
       
  1175 */
       
  1176 int
       
  1177 dwarf_get_fde_for_die(Dwarf_Debug dbg,
       
  1178 		      Dwarf_Die die,
       
  1179 		      Dwarf_Fde * ret_fde, Dwarf_Error * error)
       
  1180 {
       
  1181     Dwarf_Attribute attr;
       
  1182     Dwarf_Unsigned fde_offset = 0;
       
  1183     Dwarf_Signed signdval = 0;
       
  1184     Dwarf_Fde new_fde = 0;
       
  1185     unsigned char *fde_ptr = 0;
       
  1186     unsigned char *cie_ptr = 0;
       
  1187     Dwarf_Unsigned cie_id = 0;
       
  1188 
       
  1189     /* Fields for the current Cie being read. */
       
  1190     int res;
       
  1191     int resattr;
       
  1192     int sdatares;
       
  1193 
       
  1194     struct cie_fde_prefix_s prefix;
       
  1195     struct cie_fde_prefix_s prefix_c;
       
  1196 
       
  1197     if (die == NULL) {
       
  1198 	_dwarf_error(NULL, error, DW_DLE_DIE_NULL);
       
  1199 	return (DW_DLV_ERROR);
       
  1200     }
       
  1201 
       
  1202     resattr = dwarf_attr(die, DW_AT_MIPS_fde, &attr, error);
       
  1203     if (resattr != DW_DLV_OK) {
       
  1204 	return resattr;
       
  1205     }
       
  1206 
       
  1207     /* why is this formsdata? FIX */
       
  1208     sdatares = dwarf_formsdata(attr, &signdval, error);
       
  1209     if (sdatares != DW_DLV_OK) {
       
  1210 	return sdatares;
       
  1211     }
       
  1212 
       
  1213     res =
       
  1214 	_dwarf_load_section(dbg,
       
  1215 			    dbg->de_debug_frame_index,
       
  1216 			    &dbg->de_debug_frame, error);
       
  1217     if (res != DW_DLV_OK) {
       
  1218 	return res;
       
  1219     }
       
  1220 
       
  1221     fde_offset = signdval;
       
  1222     fde_ptr = (dbg->de_debug_frame + fde_offset);
       
  1223 
       
  1224 
       
  1225     /* First read in the 'common prefix' to figure out what * we are to 
       
  1226        do with this entry. */
       
  1227     memset(&prefix_c, 0, sizeof(prefix_c));
       
  1228     memset(&prefix, 0, sizeof(prefix));
       
  1229     res = dwarf_read_cie_fde_prefix(dbg, fde_ptr,
       
  1230 				    dbg->de_debug_frame,
       
  1231 				    dbg->de_debug_frame_index,
       
  1232 				    dbg->de_debug_frame_size, &prefix,
       
  1233 				    error);
       
  1234     if (res == DW_DLV_ERROR) {
       
  1235 	return res;
       
  1236     }
       
  1237     if (res == DW_DLV_NO_ENTRY)
       
  1238 	return res;
       
  1239     fde_ptr = prefix.cf_addr_after_prefix;
       
  1240     cie_id = prefix.cf_cie_id;
       
  1241     /* Pass NULL, not section pointer, for 3rd argument. de_debug_frame 
       
  1242        has no eh_frame relevance. */
       
  1243     res = dwarf_create_fde_from_after_start(dbg, &prefix,
       
  1244 					    (Dwarf_Small *) NULL,
       
  1245 					    fde_ptr,
       
  1246 					    /* use_gnu_cie_calc= */ 0,
       
  1247 					    /* Dwarf_Cie = */ 0,
       
  1248 					    &new_fde, error);
       
  1249 
       
  1250     if (res == DW_DLV_ERROR) {
       
  1251 	return res;
       
  1252     } else if (res == DW_DLV_NO_ENTRY) {
       
  1253 	return res;
       
  1254     }
       
  1255     /* DW_DLV_OK */
       
  1256 
       
  1257     /* now read the cie corresponding to the fde */
       
  1258     cie_ptr = new_fde->fd_section_ptr + cie_id;
       
  1259     res = dwarf_read_cie_fde_prefix(dbg, cie_ptr,
       
  1260 				    dbg->de_debug_frame,
       
  1261 				    dbg->de_debug_frame_index,
       
  1262 				    dbg->de_debug_frame_size,
       
  1263 				    &prefix_c, error);
       
  1264     if (res == DW_DLV_ERROR) {
       
  1265 	return res;
       
  1266     }
       
  1267     if (res == DW_DLV_NO_ENTRY)
       
  1268 	return res;
       
  1269 
       
  1270     cie_ptr = prefix_c.cf_addr_after_prefix;
       
  1271     cie_id = prefix_c.cf_cie_id;
       
  1272 
       
  1273 
       
  1274     if (cie_id == DW_CIE_ID) {
       
  1275 	int res2 = 0;
       
  1276 	Dwarf_Cie new_cie = 0;
       
  1277 
       
  1278 	/* Pass NULL, not section pointer, for 3rd argument.
       
  1279 	   de_debug_frame has no eh_frame relevance. */
       
  1280 	res2 = dwarf_create_cie_from_after_start(dbg,
       
  1281 						 &prefix_c,
       
  1282 						 (Dwarf_Small *) NULL,
       
  1283 						 cie_ptr,
       
  1284 						 /* cie_count= */ 0,
       
  1285 						 /* use_gnu_cie_calc= */
       
  1286 						 0, &new_cie, error);
       
  1287 	if (res2 == DW_DLV_ERROR) {
       
  1288 	    dwarf_dealloc(dbg, new_fde, DW_DLA_FDE);
       
  1289 	    return res;
       
  1290 	} else if (res2 == DW_DLV_NO_ENTRY) {
       
  1291 	    dwarf_dealloc(dbg, new_fde, DW_DLA_FDE);
       
  1292 	    return res;
       
  1293 	}
       
  1294 
       
  1295 
       
  1296 	new_fde->fd_cie = new_cie;
       
  1297 
       
  1298     } else {
       
  1299 	_dwarf_error(dbg, error, DW_DLE_NO_CIE_FOR_FDE);
       
  1300 	return (DW_DLV_ERROR);
       
  1301     }
       
  1302 
       
  1303     *ret_fde = new_fde;
       
  1304     return DW_DLV_OK;
       
  1305 }
       
  1306 
       
  1307 /* A dwarf consumer operation, see the consumer library documentation.
       
  1308 */
       
  1309 int
       
  1310 dwarf_get_fde_range(Dwarf_Fde fde,
       
  1311 		    Dwarf_Addr * low_pc,
       
  1312 		    Dwarf_Unsigned * func_length,
       
  1313 		    Dwarf_Ptr * fde_bytes,
       
  1314 		    Dwarf_Unsigned * fde_byte_length,
       
  1315 		    Dwarf_Off * cie_offset,
       
  1316 		    Dwarf_Signed * cie_index,
       
  1317 		    Dwarf_Off * fde_offset, Dwarf_Error * error)
       
  1318 {
       
  1319     Dwarf_Debug dbg;
       
  1320 
       
  1321     if (fde == NULL) {
       
  1322 	_dwarf_error(NULL, error, DW_DLE_FDE_NULL);
       
  1323 	return (DW_DLV_ERROR);
       
  1324     }
       
  1325 
       
  1326     dbg = fde->fd_dbg;
       
  1327     if (dbg == NULL) {
       
  1328 	_dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
       
  1329 	return (DW_DLV_ERROR);
       
  1330     }
       
  1331 
       
  1332 
       
  1333     /* We have always already done the section load here, so no need to 
       
  1334        load the section. We did the section load in order to create the 
       
  1335        Dwarf_Fde pointer passed in here. */
       
  1336 
       
  1337 
       
  1338     if (low_pc != NULL)
       
  1339 	*low_pc = fde->fd_initial_location;
       
  1340     if (func_length != NULL)
       
  1341 	*func_length = fde->fd_address_range;
       
  1342     if (fde_bytes != NULL)
       
  1343 	*fde_bytes = fde->fd_fde_start;
       
  1344     if (fde_byte_length != NULL)
       
  1345 	*fde_byte_length = fde->fd_length;
       
  1346     if (cie_offset != NULL)
       
  1347 	*cie_offset = fde->fd_cie_offset;
       
  1348     if (cie_index != NULL)
       
  1349 	*cie_index = fde->fd_cie_index;
       
  1350     if (fde_offset != NULL)
       
  1351 	*fde_offset = fde->fd_fde_start - fde->fd_section_ptr;
       
  1352 
       
  1353     return DW_DLV_OK;
       
  1354 }
       
  1355 
       
  1356 /* IRIX specific function.   The exception tables
       
  1357    have C++ destructor information and are
       
  1358    at present undocumented.  */
       
  1359 int
       
  1360 dwarf_get_fde_exception_info(Dwarf_Fde fde,
       
  1361 			     Dwarf_Signed *
       
  1362 			     offset_into_exception_tables,
       
  1363 			     Dwarf_Error * error)
       
  1364 {
       
  1365     Dwarf_Debug dbg;
       
  1366 
       
  1367     dbg = fde->fd_dbg;
       
  1368     if (dbg == NULL) {
       
  1369 	_dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
       
  1370 	return (DW_DLV_ERROR);
       
  1371     }
       
  1372     *offset_into_exception_tables =
       
  1373 	fde->fd_offset_into_exception_tables;
       
  1374     return DW_DLV_OK;
       
  1375 }
       
  1376 
       
  1377 
       
  1378 /* A consumer code function.
       
  1379    Given a CIE pointer, return the normal CIE data thru
       
  1380    pointers.
       
  1381    Special augmentation data is not returned here.
       
  1382 */
       
  1383 int
       
  1384 dwarf_get_cie_info(Dwarf_Cie cie,
       
  1385 		   Dwarf_Unsigned * bytes_in_cie,
       
  1386 		   Dwarf_Small * ptr_to_version,
       
  1387 		   char **augmenter,
       
  1388 		   Dwarf_Unsigned * code_alignment_factor,
       
  1389 		   Dwarf_Signed * data_alignment_factor,
       
  1390 		   Dwarf_Half * return_address_register,
       
  1391 		   Dwarf_Ptr * initial_instructions,
       
  1392 		   Dwarf_Unsigned * initial_instructions_length,
       
  1393 		   Dwarf_Error * error)
       
  1394 {
       
  1395     Dwarf_Debug dbg;
       
  1396 
       
  1397     if (cie == NULL) {
       
  1398 	_dwarf_error(NULL, error, DW_DLE_CIE_NULL);
       
  1399 	return (DW_DLV_ERROR);
       
  1400     }
       
  1401 
       
  1402     dbg = cie->ci_dbg;
       
  1403     if (dbg == NULL) {
       
  1404 	_dwarf_error(NULL, error, DW_DLE_CIE_DBG_NULL);
       
  1405 	return (DW_DLV_ERROR);
       
  1406     }
       
  1407 
       
  1408     if (ptr_to_version != NULL)
       
  1409 	*ptr_to_version = cie->ci_cie_version_number;
       
  1410     if (augmenter != NULL)
       
  1411 	*augmenter = cie->ci_augmentation;
       
  1412     if (code_alignment_factor != NULL)
       
  1413 	*code_alignment_factor = cie->ci_code_alignment_factor;
       
  1414     if (data_alignment_factor != NULL)
       
  1415 	*data_alignment_factor = cie->ci_data_alignment_factor;
       
  1416     if (return_address_register != NULL)
       
  1417 	*return_address_register = cie->ci_return_address_register;
       
  1418     if (initial_instructions != NULL)
       
  1419 	*initial_instructions = cie->ci_cie_instr_start;
       
  1420     if (initial_instructions_length != NULL) {
       
  1421 	*initial_instructions_length = cie->ci_length +
       
  1422 	    cie->ci_length_size +
       
  1423 	    cie->ci_extension_size -
       
  1424 	    (cie->ci_cie_instr_start - cie->ci_cie_start);
       
  1425 
       
  1426     }
       
  1427     *bytes_in_cie = (cie->ci_length);
       
  1428     return (DW_DLV_OK);
       
  1429 }
       
  1430 
       
  1431 /* Return the register rules for all registers at a given pc. 
       
  1432 */
       
  1433 static int
       
  1434 _dwarf_get_fde_info_for_a_pc_row(Dwarf_Fde fde,
       
  1435 				 Dwarf_Addr pc_requested,
       
  1436 				 Dwarf_Frame table,
       
  1437 				 Dwarf_Half cfa_reg_col_num,
       
  1438 				 Dwarf_Error * error)
       
  1439 {
       
  1440     Dwarf_Debug dbg = 0;
       
  1441     Dwarf_Cie cie = 0;
       
  1442     int dw_err = 0;
       
  1443     Dwarf_Sword icount = 0;
       
  1444     int res = 0;
       
  1445 
       
  1446     if (fde == NULL) {
       
  1447 	_dwarf_error(NULL, error, DW_DLE_FDE_NULL);
       
  1448 	return (DW_DLV_ERROR);
       
  1449     }
       
  1450 
       
  1451     dbg = fde->fd_dbg;
       
  1452     if (dbg == NULL) {
       
  1453 	_dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
       
  1454 	return (DW_DLV_ERROR);
       
  1455     }
       
  1456 
       
  1457     if (pc_requested < fde->fd_initial_location ||
       
  1458 	pc_requested >=
       
  1459 	fde->fd_initial_location + fde->fd_address_range) {
       
  1460 	_dwarf_error(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE);
       
  1461 	return (DW_DLV_ERROR);
       
  1462     }
       
  1463 
       
  1464     cie = fde->fd_cie;
       
  1465     if (cie->ci_initial_table == NULL) {
       
  1466 	cie->ci_initial_table = _dwarf_get_alloc(dbg, DW_DLA_FRAME, 1);
       
  1467 
       
  1468 	if (cie->ci_initial_table == NULL) {
       
  1469 	    _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
       
  1470 	    return (DW_DLV_ERROR);
       
  1471 	}
       
  1472 	_dwarf_init_regrule_table(cie->ci_initial_table->fr_reg,
       
  1473 				  dbg->de_frame_reg_rules_entry_count,
       
  1474 				  dbg->de_frame_rule_initial_value);
       
  1475 	_dwarf_init_regrule_table(&cie->ci_initial_table->fr_cfa_rule,
       
  1476 				  1, dbg->de_frame_rule_initial_value);
       
  1477 	res = _dwarf_exec_frame_instr( /* make_instr= */ false,
       
  1478 				      /* ret_frame_instr= */ NULL,
       
  1479 				      /* search_pc */ false,
       
  1480 				      /* search_pc_val */ 0,
       
  1481 				      /* location */ 0,
       
  1482 				      cie->ci_cie_instr_start,
       
  1483 				      cie->ci_cie_instr_start +
       
  1484 				      (cie->ci_length +
       
  1485 				       cie->ci_length_size +
       
  1486 				       cie->ci_extension_size -
       
  1487 				       (cie->ci_cie_instr_start -
       
  1488 					cie->ci_cie_start)),
       
  1489 				      cie->ci_initial_table, cie, dbg,
       
  1490 				      cfa_reg_col_num, &icount,
       
  1491 				      &dw_err);
       
  1492 	if (res == DW_DLV_ERROR) {
       
  1493 	    _dwarf_error(dbg, error, dw_err);
       
  1494 	    return (res);
       
  1495 	} else if (res == DW_DLV_NO_ENTRY) {
       
  1496 	    return res;
       
  1497 	}
       
  1498     }
       
  1499 
       
  1500     {
       
  1501 	Dwarf_Small *instr_end = fde->fd_fde_instr_start +
       
  1502 	    fde->fd_length +
       
  1503 	    fde->fd_length_size +
       
  1504 	    fde->fd_extension_size - (fde->fd_fde_instr_start -
       
  1505 				      fde->fd_fde_start);
       
  1506 
       
  1507 	res = _dwarf_exec_frame_instr( /* make_instr= */ false,
       
  1508 				      /* ret_frame_instr= */ NULL,
       
  1509 				      /* search_pc */ true,
       
  1510 				      /* search_pc_val */ pc_requested,
       
  1511 				      fde->fd_initial_location,
       
  1512 				      fde->fd_fde_instr_start,
       
  1513 				      instr_end,
       
  1514 				      table,
       
  1515 				      cie, dbg,
       
  1516 				      cfa_reg_col_num, &icount,
       
  1517 				      &dw_err);
       
  1518     }
       
  1519     if (res == DW_DLV_ERROR) {
       
  1520 	_dwarf_error(dbg, error, dw_err);
       
  1521 	return (res);
       
  1522     } else if (res == DW_DLV_NO_ENTRY) {
       
  1523 	return res;
       
  1524     }
       
  1525 
       
  1526     return DW_DLV_OK;
       
  1527 }
       
  1528 
       
  1529 /* A consumer call for efficiently getting the register info
       
  1530    for all registers in one call.
       
  1531 
       
  1532    The output table rules array is size DW_REG_TABLE_SIZE.
       
  1533    The frame info  rules array in fde_table is of size
       
  1534    DW_REG_TABLE_SIZE too.
       
  1535 
       
  1536    This interface  really only works well with MIPS/IRIX
       
  1537    where DW_FRAME_CFA_COL is zero (in that case it's safe).
       
  1538 
       
  1539    It is also restricted to the case  where
       
  1540    DW_REG_TABLE_SIZE == DW_FRAME_LAST_REG_NUM  ==
       
  1541    dbg->de_frame_reg_rules_entry_count (true for MIPS/IRIX).
       
  1542    If this condition is not met calling this routine can result in
       
  1543    incorrect output or in memory corruption.
       
  1544 
       
  1545 */
       
  1546 int
       
  1547 dwarf_get_fde_info_for_all_regs(Dwarf_Fde fde,
       
  1548 				Dwarf_Addr pc_requested,
       
  1549 				Dwarf_Regtable * reg_table,
       
  1550 				Dwarf_Addr * row_pc,
       
  1551 				Dwarf_Error * error)
       
  1552 {
       
  1553 
       
  1554     /* Table size: DW_REG_TABLE_SIZE */
       
  1555     struct Dwarf_Frame_s fde_table;
       
  1556     Dwarf_Sword i = 0;
       
  1557     struct Dwarf_Reg_Rule_s *rule = NULL;
       
  1558     struct Dwarf_Regtable_Entry_s *out_rule = NULL;
       
  1559     int res = 0;
       
  1560     Dwarf_Debug dbg = 0;
       
  1561 
       
  1562     /* For this interface the size is fixed at compile time. */
       
  1563     int output_table_real_data_size = DW_REG_TABLE_SIZE;
       
  1564 
       
  1565     FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg);
       
  1566 
       
  1567     res = dwarf_initialize_fde_table(dbg, &fde_table,
       
  1568 				     output_table_real_data_size,
       
  1569 				     error);
       
  1570     if (res != DW_DLV_OK)
       
  1571 	return res;
       
  1572 
       
  1573 
       
  1574 
       
  1575     /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks 
       
  1576      */
       
  1577     res = _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested,
       
  1578 					   &fde_table,
       
  1579 					   DW_FRAME_CFA_COL, error);
       
  1580     if (res != DW_DLV_OK) {
       
  1581 	dwarf_free_fde_table(&fde_table);
       
  1582 	return res;
       
  1583     }
       
  1584 
       
  1585     out_rule = &reg_table->rules[0];
       
  1586     rule = &fde_table.fr_reg[0];
       
  1587     for (i = 0; i < output_table_real_data_size;
       
  1588 	 i++, ++out_rule, ++rule) {
       
  1589 	out_rule->dw_offset_relevant = rule->ru_is_off;
       
  1590 	out_rule->dw_value_type = rule->ru_value_type;
       
  1591 	out_rule->dw_regnum = rule->ru_register;
       
  1592 	out_rule->dw_offset = rule->ru_offset_or_block_len;
       
  1593     }
       
  1594     for (; i < DW_REG_TABLE_SIZE; ++i, ++out_rule) {
       
  1595 	out_rule->dw_offset_relevant = 0;
       
  1596 	out_rule->dw_value_type = DW_EXPR_OFFSET;
       
  1597 	out_rule->dw_regnum = DW_FRAME_UNDEFINED_VAL;
       
  1598 	out_rule->dw_offset = 0;
       
  1599     }
       
  1600 
       
  1601     /* The test is just in case it's not inside the table. For non-MIPS 
       
  1602        it could be outside the table and that is just fine, it was
       
  1603        really a mistake to put it in the table in 1993.  */
       
  1604     /* CONSTCOND */
       
  1605     if (DW_FRAME_CFA_COL < DW_REG_TABLE_SIZE) {
       
  1606 	out_rule = &reg_table->rules[DW_FRAME_CFA_COL];
       
  1607 	out_rule->dw_offset_relevant = fde_table.fr_cfa_rule.ru_is_off;
       
  1608 	out_rule->dw_value_type = fde_table.fr_cfa_rule.ru_value_type;
       
  1609 	out_rule->dw_regnum = fde_table.fr_cfa_rule.ru_register;
       
  1610 	out_rule->dw_offset =
       
  1611 	    fde_table.fr_cfa_rule.ru_offset_or_block_len;
       
  1612     }
       
  1613 
       
  1614     if (row_pc != NULL)
       
  1615 	*row_pc = fde_table.fr_loc;
       
  1616     dwarf_free_fde_table(&fde_table);
       
  1617     return DW_DLV_OK;
       
  1618 }
       
  1619 
       
  1620 /* A consumer call for efficiently getting the register info
       
  1621    for all registers in one call.
       
  1622 
       
  1623    The output table rules array is size output_table_real_data_size.
       
  1624    (normally  DW_REG_TABLE_SIZE).
       
  1625    The frame info  rules array in fde_table is normally of size
       
  1626    DW_FRAME_LAST_REG_NUM.
       
  1627 */
       
  1628 int
       
  1629 dwarf_get_fde_info_for_all_regs3(Dwarf_Fde fde,
       
  1630 				 Dwarf_Addr pc_requested,
       
  1631 				 Dwarf_Regtable3 * reg_table,
       
  1632 				 Dwarf_Addr * row_pc,
       
  1633 				 Dwarf_Error * error)
       
  1634 {
       
  1635 
       
  1636     struct Dwarf_Frame_s fde_table;
       
  1637     Dwarf_Sword i = 0;
       
  1638     int res = 0;
       
  1639     struct Dwarf_Reg_Rule_s *rule = NULL;
       
  1640     struct Dwarf_Regtable_Entry3_s *out_rule = NULL;
       
  1641     Dwarf_Debug dbg = 0;
       
  1642     int output_table_real_data_size = reg_table->rt3_reg_table_size;
       
  1643 
       
  1644     FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg);
       
  1645 
       
  1646     output_table_real_data_size =
       
  1647 	MIN(output_table_real_data_size,
       
  1648 	    dbg->de_frame_reg_rules_entry_count);
       
  1649 
       
  1650     res = dwarf_initialize_fde_table(dbg, &fde_table,
       
  1651 				     output_table_real_data_size,
       
  1652 				     error);
       
  1653 
       
  1654     /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks 
       
  1655      */
       
  1656     res = _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested,
       
  1657 					   &fde_table,
       
  1658 					   DW_FRAME_CFA_COL3, error);
       
  1659     if (res != DW_DLV_OK) {
       
  1660 	dwarf_free_fde_table(&fde_table);
       
  1661 	return res;
       
  1662     }
       
  1663 
       
  1664     out_rule = &reg_table->rt3_rules[0];
       
  1665     rule = &fde_table.fr_reg[0];
       
  1666     for (i = 0; i < output_table_real_data_size;
       
  1667 	 i++, ++out_rule, ++rule) {
       
  1668 	out_rule->dw_offset_relevant = rule->ru_is_off;
       
  1669 	out_rule->dw_value_type = rule->ru_value_type;
       
  1670 	out_rule->dw_regnum = rule->ru_register;
       
  1671 	out_rule->dw_offset_or_block_len = rule->ru_offset_or_block_len;
       
  1672 	out_rule->dw_block_ptr = rule->ru_block;
       
  1673     }
       
  1674     for (; i < reg_table->rt3_reg_table_size; i++, ++out_rule) {
       
  1675 	out_rule->dw_offset_relevant = 0;
       
  1676 	out_rule->dw_value_type = DW_EXPR_OFFSET;
       
  1677 	out_rule->dw_regnum = DW_FRAME_UNDEFINED_VAL;
       
  1678 	out_rule->dw_offset_or_block_len = 0;
       
  1679 	out_rule->dw_block_ptr = 0;
       
  1680     }
       
  1681     reg_table->rt3_cfa_rule.dw_offset_relevant =
       
  1682 	fde_table.fr_cfa_rule.ru_is_off;
       
  1683     reg_table->rt3_cfa_rule.dw_value_type =
       
  1684 	fde_table.fr_cfa_rule.ru_value_type;
       
  1685     reg_table->rt3_cfa_rule.dw_regnum =
       
  1686 	fde_table.fr_cfa_rule.ru_register;
       
  1687     reg_table->rt3_cfa_rule.dw_offset_or_block_len =
       
  1688 	fde_table.fr_cfa_rule.ru_offset_or_block_len;
       
  1689     reg_table->rt3_cfa_rule.dw_block_ptr =
       
  1690 	fde_table.fr_cfa_rule.ru_block;
       
  1691 
       
  1692     if (row_pc != NULL)
       
  1693 	*row_pc = fde_table.fr_loc;
       
  1694 
       
  1695     dwarf_free_fde_table(&fde_table);
       
  1696     return DW_DLV_OK;
       
  1697 }
       
  1698 
       
  1699 
       
  1700 /* Gets the register info for a single register at a given PC value
       
  1701    for the FDE specified.
       
  1702 
       
  1703 */
       
  1704 int
       
  1705 dwarf_get_fde_info_for_reg(Dwarf_Fde fde,
       
  1706 			   Dwarf_Half table_column,
       
  1707 			   Dwarf_Addr pc_requested,
       
  1708 			   Dwarf_Signed * offset_relevant,
       
  1709 			   Dwarf_Signed * register_num,
       
  1710 			   Dwarf_Signed * offset,
       
  1711 			   Dwarf_Addr * row_pc, Dwarf_Error * error)
       
  1712 {
       
  1713     struct Dwarf_Frame_s fde_table;
       
  1714     int res;
       
  1715     Dwarf_Debug dbg = 0;
       
  1716     int output_table_real_data_size = 0;
       
  1717 
       
  1718     FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg);
       
  1719     output_table_real_data_size = dbg->de_frame_reg_rules_entry_count;
       
  1720 
       
  1721     res = dwarf_initialize_fde_table(dbg, &fde_table,
       
  1722 				     output_table_real_data_size,
       
  1723 				     error);
       
  1724     if (res != DW_DLV_OK)
       
  1725 	return res;
       
  1726 
       
  1727 
       
  1728     if (table_column >= output_table_real_data_size) {
       
  1729 	dwarf_free_fde_table(&fde_table);
       
  1730 	_dwarf_error(dbg, error, DW_DLE_FRAME_TABLE_COL_BAD);
       
  1731 	return (DW_DLV_ERROR);
       
  1732     }
       
  1733 
       
  1734     /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks 
       
  1735      */
       
  1736     res =
       
  1737 	_dwarf_get_fde_info_for_a_pc_row(fde, pc_requested, &fde_table,
       
  1738 					 DW_FRAME_CFA_COL, error);
       
  1739     if (res != DW_DLV_OK) {
       
  1740 	dwarf_free_fde_table(&fde_table);
       
  1741 	return res;
       
  1742     }
       
  1743 
       
  1744     if (fde_table.fr_reg[table_column].ru_value_type != DW_EXPR_OFFSET) {
       
  1745 	dwarf_free_fde_table(&fde_table);
       
  1746 	_dwarf_error(NULL, error,
       
  1747 		     DW_DLE_FRAME_REGISTER_UNREPRESENTABLE);
       
  1748 	return (DW_DLV_ERROR);
       
  1749     }
       
  1750 
       
  1751     if (register_num != NULL)
       
  1752 	*register_num = fde_table.fr_reg[table_column].ru_register;
       
  1753     if (offset != NULL)
       
  1754 	*offset = fde_table.fr_reg[table_column].ru_offset_or_block_len;
       
  1755     if (row_pc != NULL)
       
  1756 	*row_pc = fde_table.fr_loc;
       
  1757 
       
  1758     *offset_relevant = (fde_table.fr_reg[table_column].ru_is_off);
       
  1759     dwarf_free_fde_table(&fde_table);
       
  1760     return DW_DLV_OK;
       
  1761 }
       
  1762 
       
  1763 /* In this interface, table_column of DW_FRAME_CFA_COL
       
  1764    is not meaningful.
       
  1765    Use  dwarf_get_fde_info_for_cfa_reg3() to get the CFA.
       
  1766 */
       
  1767 int
       
  1768 dwarf_get_fde_info_for_reg3(Dwarf_Fde fde,
       
  1769 			    Dwarf_Half table_column,
       
  1770 			    Dwarf_Addr pc_requested,
       
  1771 			    Dwarf_Small * value_type,
       
  1772 			    Dwarf_Signed * offset_relevant,
       
  1773 			    Dwarf_Signed * register_num,
       
  1774 			    Dwarf_Signed * offset_or_block_len,
       
  1775 			    Dwarf_Ptr * block_ptr,
       
  1776 			    Dwarf_Addr * row_pc_out,
       
  1777 			    Dwarf_Error * error)
       
  1778 {
       
  1779     struct Dwarf_Frame_s fde_table;
       
  1780     int res = 0;
       
  1781 
       
  1782     Dwarf_Debug dbg = 0;
       
  1783     int table_real_data_size = 0;
       
  1784 
       
  1785     FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg);
       
  1786     table_real_data_size = dbg->de_frame_reg_rules_entry_count;
       
  1787     res = dwarf_initialize_fde_table(dbg, &fde_table,
       
  1788 				     table_real_data_size, error);
       
  1789     if (res != DW_DLV_OK)
       
  1790 	return res;
       
  1791     if (table_column >= table_real_data_size) {
       
  1792 	dwarf_free_fde_table(&fde_table);
       
  1793 	_dwarf_error(dbg, error, DW_DLE_FRAME_TABLE_COL_BAD);
       
  1794 	return (DW_DLV_ERROR);
       
  1795     }
       
  1796 
       
  1797     /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks 
       
  1798      */
       
  1799     res =
       
  1800 	_dwarf_get_fde_info_for_a_pc_row(fde, pc_requested, &fde_table,
       
  1801 					 DW_FRAME_CFA_COL3, error);
       
  1802     if (res != DW_DLV_OK) {
       
  1803 	dwarf_free_fde_table(&fde_table);
       
  1804 	return res;
       
  1805     }
       
  1806 
       
  1807     if (register_num != NULL)
       
  1808 	*register_num = fde_table.fr_reg[table_column].ru_register;
       
  1809     if (offset_or_block_len != NULL)
       
  1810 	*offset_or_block_len =
       
  1811 	    fde_table.fr_reg[table_column].ru_offset_or_block_len;
       
  1812     if (row_pc_out != NULL)
       
  1813 	*row_pc_out = fde_table.fr_loc;
       
  1814     if (block_ptr)
       
  1815 	*block_ptr = fde_table.fr_reg[table_column].ru_block;
       
  1816 
       
  1817     /* Without value_type the data cannot be understood, so we insist
       
  1818        on it being present, we don't test it. */
       
  1819     *value_type = fde_table.fr_reg[table_column].ru_value_type;
       
  1820     *offset_relevant = (fde_table.fr_reg[table_column].ru_is_off);
       
  1821     dwarf_free_fde_table(&fde_table);
       
  1822     return DW_DLV_OK;
       
  1823 
       
  1824 }
       
  1825 
       
  1826 /* For latest DWARF, this is the preferred interface.
       
  1827    It more portably deals with the  CFA by not
       
  1828    making the CFA a column number, which means
       
  1829    DW_FRAME_CFA_COL becomes an index like DW_CFA_SAME_VALUE,
       
  1830    a special value, not something one uses as an index.  */
       
  1831 int
       
  1832 dwarf_get_fde_info_for_cfa_reg3(Dwarf_Fde fde,
       
  1833 				Dwarf_Addr pc_requested,
       
  1834 				Dwarf_Small * value_type,
       
  1835 				Dwarf_Signed * offset_relevant,
       
  1836 				Dwarf_Signed * register_num,
       
  1837 				Dwarf_Signed * offset_or_block_len,
       
  1838 				Dwarf_Ptr * block_ptr,
       
  1839 				Dwarf_Addr * row_pc_out,
       
  1840 				Dwarf_Error * error)
       
  1841 {
       
  1842     struct Dwarf_Frame_s fde_table;
       
  1843     int res;
       
  1844     Dwarf_Debug dbg = 0;
       
  1845 
       
  1846     int table_real_data_size = 0;
       
  1847 
       
  1848     FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg);
       
  1849 
       
  1850     table_real_data_size = dbg->de_frame_reg_rules_entry_count;
       
  1851     res = dwarf_initialize_fde_table(dbg, &fde_table,
       
  1852 				     table_real_data_size, error);
       
  1853     if (res != DW_DLV_OK)
       
  1854 	return res;
       
  1855     res =
       
  1856 	_dwarf_get_fde_info_for_a_pc_row(fde, pc_requested, &fde_table,
       
  1857 					 DW_FRAME_CFA_COL3, error);
       
  1858     if (res != DW_DLV_OK) {
       
  1859 	dwarf_free_fde_table(&fde_table);
       
  1860 	return res;
       
  1861     }
       
  1862 
       
  1863     if (register_num != NULL)
       
  1864 	*register_num = fde_table.fr_cfa_rule.ru_register;
       
  1865     if (offset_or_block_len != NULL)
       
  1866 	*offset_or_block_len =
       
  1867 	    fde_table.fr_cfa_rule.ru_offset_or_block_len;
       
  1868     if (row_pc_out != NULL)
       
  1869 	*row_pc_out = fde_table.fr_loc;
       
  1870     if (block_ptr)
       
  1871 	*block_ptr = fde_table.fr_cfa_rule.ru_block;
       
  1872 
       
  1873     /* Without value_type the data cannot be understood, so we insist
       
  1874        on it being present, we don't test it. */
       
  1875     *value_type = fde_table.fr_cfa_rule.ru_value_type;
       
  1876     *offset_relevant = fde_table.fr_cfa_rule.ru_is_off;
       
  1877     dwarf_free_fde_table(&fde_table);
       
  1878     return DW_DLV_OK;
       
  1879 }
       
  1880 
       
  1881 
       
  1882 
       
  1883 /*
       
  1884 	Return pointer to the instructions in the dwarf
       
  1885 	fde.
       
  1886 */
       
  1887 int
       
  1888 dwarf_get_fde_instr_bytes(Dwarf_Fde inFde, Dwarf_Ptr * outinstraddr,
       
  1889 			  Dwarf_Unsigned * outaddrlen,
       
  1890 			  Dwarf_Error * error)
       
  1891 {
       
  1892     Dwarf_Unsigned len = 0;
       
  1893     unsigned char *instrs = 0;
       
  1894     Dwarf_Debug dbg = 0;
       
  1895 
       
  1896     if (inFde == NULL) {
       
  1897 	_dwarf_error(dbg, error, DW_DLE_FDE_NULL);
       
  1898 	return (DW_DLV_ERROR);
       
  1899     }
       
  1900 
       
  1901     dbg = inFde->fd_dbg;
       
  1902     if (dbg == NULL) {
       
  1903 	_dwarf_error(dbg, error, DW_DLE_FDE_DBG_NULL);
       
  1904 	return (DW_DLV_ERROR);
       
  1905     }
       
  1906 
       
  1907     instrs = inFde->fd_fde_instr_start;
       
  1908 
       
  1909     len = (inFde->fd_fde_start + inFde->fd_length +
       
  1910 	   inFde->fd_length_size + inFde->fd_extension_size) - instrs;
       
  1911 
       
  1912     *outinstraddr = instrs;
       
  1913     *outaddrlen = len;
       
  1914     return DW_DLV_OK;
       
  1915 }
       
  1916 
       
  1917 /* Allows getting an fde from its table via an index.  
       
  1918    With more error checking than simply indexing oneself.
       
  1919 */
       
  1920 int
       
  1921 dwarf_get_fde_n(Dwarf_Fde * fde_data,
       
  1922 		Dwarf_Unsigned fde_index,
       
  1923 		Dwarf_Fde * returned_fde, Dwarf_Error * error)
       
  1924 {
       
  1925     Dwarf_Debug dbg = 0;
       
  1926 
       
  1927     if (fde_data == NULL) {
       
  1928 	_dwarf_error(dbg, error, DW_DLE_FDE_PTR_NULL);
       
  1929 	return (DW_DLV_ERROR);
       
  1930     }
       
  1931 
       
  1932     FDE_NULL_CHECKS_AND_SET_DBG(*fde_data, dbg);
       
  1933 
       
  1934     if (fde_index >= dbg->de_fde_count) {
       
  1935 	return (DW_DLV_NO_ENTRY);
       
  1936     }
       
  1937     *returned_fde = (*(fde_data + fde_index));
       
  1938     return DW_DLV_OK;
       
  1939 }
       
  1940 
       
  1941 
       
  1942 /* 
       
  1943     Lopc and hipc are extensions to the interface to 
       
  1944     return the range of addresses that are described
       
  1945     by the returned fde.
       
  1946 */
       
  1947 int
       
  1948 dwarf_get_fde_at_pc(Dwarf_Fde * fde_data,
       
  1949 		    Dwarf_Addr pc_of_interest,
       
  1950 		    Dwarf_Fde * returned_fde,
       
  1951 		    Dwarf_Addr * lopc,
       
  1952 		    Dwarf_Addr * hipc, Dwarf_Error * error)
       
  1953 {
       
  1954     Dwarf_Debug dbg = NULL;
       
  1955     Dwarf_Fde fde = NULL;
       
  1956     Dwarf_Fde entryfde = NULL;
       
  1957 
       
  1958     if (fde_data == NULL) {
       
  1959 	_dwarf_error(NULL, error, DW_DLE_FDE_PTR_NULL);
       
  1960 	return (DW_DLV_ERROR);
       
  1961     }
       
  1962 
       
  1963     /* Assumes fde_data table has at least one entry. */
       
  1964     entryfde = *fde_data;
       
  1965     FDE_NULL_CHECKS_AND_SET_DBG(entryfde, dbg);
       
  1966 
       
  1967     if (dbg == NULL) {
       
  1968 	_dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
       
  1969 	return (DW_DLV_ERROR);
       
  1970     }
       
  1971     {
       
  1972 	/* The fde's are sorted by their addresses. Binary search to
       
  1973 	   find correct fde. */
       
  1974 	Dwarf_Signed low = 0;
       
  1975 	Dwarf_Signed high = dbg->de_fde_count - 1L;
       
  1976 	Dwarf_Signed middle = 0;
       
  1977 	Dwarf_Fde cur_fde;
       
  1978 
       
  1979 	while (low <= high) {
       
  1980 	    middle = (low + high) / 2;
       
  1981 	    cur_fde = fde_data[middle];
       
  1982 	    if (pc_of_interest < cur_fde->fd_initial_location) {
       
  1983 		high = middle - 1;
       
  1984 	    } else if (pc_of_interest >=
       
  1985 		       (cur_fde->fd_initial_location +
       
  1986 			cur_fde->fd_address_range)) {
       
  1987 		low = middle + 1;
       
  1988 	    } else {
       
  1989 		fde = fde_data[middle];
       
  1990 		break;
       
  1991 	    }
       
  1992 	}
       
  1993     }
       
  1994 
       
  1995     if (fde) {
       
  1996 	if (lopc != NULL)
       
  1997 	    *lopc = fde->fd_initial_location;
       
  1998 	if (hipc != NULL)
       
  1999 	    *hipc =
       
  2000 		fde->fd_initial_location + fde->fd_address_range - 1;
       
  2001 	*returned_fde = fde;
       
  2002 	return (DW_DLV_OK);
       
  2003     }
       
  2004 
       
  2005     return (DW_DLV_NO_ENTRY);
       
  2006 }
       
  2007 
       
  2008 
       
  2009 /* Expands a single frame instruction block
       
  2010    into a n array of Dwarf_Frame_Op-s.
       
  2011 */
       
  2012 int
       
  2013 dwarf_expand_frame_instructions(Dwarf_Debug dbg,
       
  2014 				Dwarf_Ptr instruction,
       
  2015 				Dwarf_Unsigned i_length,
       
  2016 				Dwarf_Frame_Op ** returned_op_list,
       
  2017 				Dwarf_Signed * returned_op_count,
       
  2018 				Dwarf_Error * error)
       
  2019 {
       
  2020     Dwarf_Sword instr_count;
       
  2021     int res;
       
  2022     int dw_err;
       
  2023 
       
  2024     if (dbg == 0) {
       
  2025 	_dwarf_error(NULL, error, DW_DLE_DBG_NULL);
       
  2026 	return (DW_DLV_ERROR);
       
  2027     }
       
  2028 
       
  2029     if (returned_op_list == 0 || returned_op_count == 0) {
       
  2030 	_dwarf_error(dbg, error, DW_DLE_RET_OP_LIST_NULL);
       
  2031 	return (DW_DLV_ERROR);
       
  2032     }
       
  2033 
       
  2034     /* The cast to Dwarf_Ptr may get a compiler warning, but it is safe 
       
  2035        as it is just an i_length offset from 'instruction' itself. A
       
  2036        caller has made a big mistake if the result is not a valid
       
  2037        pointer. */
       
  2038     res = _dwarf_exec_frame_instr( /* make_instr= */ true,
       
  2039 				  returned_op_list,
       
  2040 				  /* search_pc */ false,
       
  2041 				  /* search_pc_val */ 0,
       
  2042 				  /* location */ 0,
       
  2043 				  instruction,
       
  2044 				  (Dwarf_Ptr) ((Dwarf_Unsigned)
       
  2045 					       instruction + i_length),
       
  2046 				  /* Dwarf_Frame */ NULL,
       
  2047 				  /* cie_ptr */ NULL,
       
  2048 				  dbg,
       
  2049 				  DW_FRAME_CFA_COL, &instr_count,
       
  2050 				  &dw_err);
       
  2051     if (res != DW_DLV_OK) {
       
  2052 	if (res == DW_DLV_ERROR) {
       
  2053 	    _dwarf_error(dbg, error, dw_err);
       
  2054 	}
       
  2055 	return (res);
       
  2056     }
       
  2057 
       
  2058     *returned_op_count = instr_count;
       
  2059     return DW_DLV_OK;
       
  2060 }
       
  2061 
       
  2062 
       
  2063 /* Used by dwarfdump -v to print offsets, for debugging
       
  2064    dwarf info.
       
  2065    The dwarf_ version is preferred over the obsolete _dwarf version.
       
  2066    _dwarf version kept for compatibility.
       
  2067 */
       
  2068 /* ARGSUSED 4 */
       
  2069 int
       
  2070 _dwarf_fde_section_offset(Dwarf_Debug dbg, Dwarf_Fde in_fde,
       
  2071 			  Dwarf_Off * fde_off, Dwarf_Off * cie_off,
       
  2072 			  Dwarf_Error * err) 
       
  2073 {
       
  2074   return _dwarf_fde_section_offset(dbg,in_fde,fde_off,
       
  2075      cie_off,err);
       
  2076 }
       
  2077 /* ARGSUSED 4 */
       
  2078 int
       
  2079 dwarf_fde_section_offset(Dwarf_Debug dbg, Dwarf_Fde in_fde,
       
  2080 			  Dwarf_Off * fde_off, Dwarf_Off * cie_off,
       
  2081 			  Dwarf_Error * err)
       
  2082 {
       
  2083     char *start = 0;
       
  2084     char *loc = 0;
       
  2085 
       
  2086 
       
  2087 
       
  2088     start = (char *) in_fde->fd_section_ptr;
       
  2089     loc = (char *) in_fde->fd_fde_start;
       
  2090 
       
  2091     *fde_off = (loc - start);
       
  2092     *cie_off = in_fde->fd_cie_offset;
       
  2093     return DW_DLV_OK;
       
  2094 }
       
  2095 
       
  2096 /* Used by dwarfdump -v to print offsets, for debugging
       
  2097    dwarf info.
       
  2098    The dwarf_ version is preferred over the obsolete _dwarf version.
       
  2099    _dwarf version kept for compatibility.
       
  2100 */
       
  2101 /* ARGSUSED 4 */
       
  2102 int
       
  2103 _dwarf_cie_section_offset(Dwarf_Debug dbg, Dwarf_Cie in_cie,
       
  2104 			  Dwarf_Off * cie_off, Dwarf_Error * err)
       
  2105 {
       
  2106     return dwarf_cie_section_offset(dbg,in_cie,cie_off,err);
       
  2107 }
       
  2108 /* ARGSUSED 4 */
       
  2109 int
       
  2110 dwarf_cie_section_offset(Dwarf_Debug dbg, Dwarf_Cie in_cie,
       
  2111 			  Dwarf_Off * cie_off, Dwarf_Error * err)
       
  2112 {
       
  2113     char *start = 0;
       
  2114     char *loc = 0;
       
  2115 
       
  2116     start = (char *) in_cie->ci_section_ptr;
       
  2117     loc = (char *) in_cie->ci_cie_start;
       
  2118 
       
  2119     *cie_off = (loc - start);
       
  2120     return DW_DLV_OK;
       
  2121 }
       
  2122 
       
  2123 /* Returns  a pointer to target-specific augmentation data thru augdata
       
  2124    and returns the length of the data thru augdata_len.
       
  2125 
       
  2126    It's up to the consumer code to know how to interpret the bytes
       
  2127    of target-specific data (endian issues apply too, these
       
  2128    are just raw bytes pointed to).
       
  2129    See  Linux Standard Base Core Specification version 3.0 for
       
  2130    the details on .eh_frame info.
       
  2131 
       
  2132    Returns DW_DLV_ERROR if fde is NULL or some other serious
       
  2133    error.
       
  2134    Returns DW_DLV_NO_ENTRY if there is no target-specific
       
  2135    augmentation data. 
       
  2136 
       
  2137    The bytes pointed to are in the Dwarf_Cie, and as long as that
       
  2138    is valid the bytes are there. No 'dealloc' call is needed
       
  2139    for the bytes.
       
  2140 */
       
  2141 int
       
  2142 dwarf_get_cie_augmentation_data(Dwarf_Cie cie,
       
  2143 				Dwarf_Small ** augdata,
       
  2144 				Dwarf_Unsigned * augdata_len,
       
  2145 				Dwarf_Error * error)
       
  2146 {
       
  2147     if (cie == NULL) {
       
  2148 	_dwarf_error(NULL, error, DW_DLE_CIE_NULL);
       
  2149 	return (DW_DLV_ERROR);
       
  2150     }
       
  2151     if (cie->ci_gnu_eh_augmentation_len == 0) {
       
  2152 	return DW_DLV_NO_ENTRY;
       
  2153     }
       
  2154     *augdata = (Dwarf_Small *) (cie->ci_gnu_eh_augmentation_bytes);
       
  2155     *augdata_len = cie->ci_gnu_eh_augmentation_len;
       
  2156     return DW_DLV_OK;
       
  2157 }
       
  2158 
       
  2159 
       
  2160 /* Returns  a pointer to target-specific augmentation data thru augdata
       
  2161    and returns the length of the data thru augdata_len.
       
  2162 
       
  2163    It's up to the consumer code to know how to interpret the bytes
       
  2164    of target-specific data (endian issues apply too, these
       
  2165    are just raw bytes pointed to).
       
  2166    See  Linux Standard Base Core Specification version 3.0 for
       
  2167    the details on .eh_frame info.
       
  2168 
       
  2169    Returns DW_DLV_ERROR if fde is NULL or some other serious
       
  2170    error.
       
  2171    Returns DW_DLV_NO_ENTRY if there is no target-specific
       
  2172    augmentation data. 
       
  2173 
       
  2174    The bytes pointed to are in the Dwarf_Fde, and as long as that
       
  2175    is valid the bytes are there. No 'dealloc' call is needed
       
  2176    for the bytes.
       
  2177 
       
  2178 */
       
  2179 int
       
  2180 dwarf_get_fde_augmentation_data(Dwarf_Fde fde,
       
  2181 				Dwarf_Small * *augdata,
       
  2182 				Dwarf_Unsigned * augdata_len,
       
  2183 				Dwarf_Error * error)
       
  2184 {
       
  2185     Dwarf_Cie cie = 0;
       
  2186 
       
  2187     if (fde == NULL) {
       
  2188 	_dwarf_error(NULL, error, DW_DLE_FDE_NULL);
       
  2189 	return (DW_DLV_ERROR);
       
  2190     }
       
  2191     cie = fde->fd_cie;
       
  2192     if (cie == NULL) {
       
  2193 	_dwarf_error(NULL, error, DW_DLE_CIE_NULL);
       
  2194 	return (DW_DLV_ERROR);
       
  2195     }
       
  2196     if (cie->ci_gnu_eh_augmentation_len == 0) {
       
  2197 	return DW_DLV_NO_ENTRY;
       
  2198     }
       
  2199     *augdata = (Dwarf_Small *) fde->fd_gnu_eh_augmentation_bytes;
       
  2200     *augdata_len = fde->fd_gnu_eh_augmentation_len;
       
  2201     return DW_DLV_OK;
       
  2202 }
       
  2203 
       
  2204 
       
  2205 /* Initialize with same_value , a value which makes sense
       
  2206    for IRIX/MIPS.
       
  2207    The correct value to use is ABI dependent.
       
  2208    For register-windows machines most
       
  2209    or all registers should get DW_FRAME_UNDEFINED_VAL as the
       
  2210    correct initial value.
       
  2211    Some think DW_FRAME_UNDEFINED_VAL is always the
       
  2212    right value.   
       
  2213 
       
  2214    For some ABIs a setting which varies by register
       
  2215    would be more appropriate.
       
  2216 
       
  2217    FIXME. */
       
  2218 
       
  2219 static void
       
  2220 _dwarf_init_regrule_table(struct Dwarf_Reg_Rule_s *t1reg,
       
  2221 			  int last_reg_num, int initial_value)
       
  2222 {
       
  2223     struct Dwarf_Reg_Rule_s *t1end = t1reg + last_reg_num;
       
  2224 
       
  2225     for (; t1reg < t1end; t1reg++) {
       
  2226 	t1reg->ru_is_off = 0;
       
  2227 	t1reg->ru_value_type = DW_EXPR_OFFSET;
       
  2228 	t1reg->ru_register = initial_value;
       
  2229 	t1reg->ru_offset_or_block_len = 0;
       
  2230 	t1reg->ru_block = 0;
       
  2231     }
       
  2232 }
       
  2233 
       
  2234 #if 0
       
  2235 /* Used solely for debugging libdwarf. */
       
  2236 static void
       
  2237 dump_frame_rule(char *msg, struct Dwarf_Reg_Rule_s *reg_rule)
       
  2238 {
       
  2239     printf
       
  2240 	("%s type %s (0x%x), is_off %d reg %d offset 0x%llx blockp 0x%llx \n",
       
  2241 	 msg,
       
  2242 	 (reg_rule->ru_value_type ==
       
  2243 	  DW_EXPR_OFFSET) ? "DW_EXPR_OFFSET" : (reg_rule->
       
  2244 						ru_value_type ==
       
  2245 						DW_EXPR_VAL_OFFSET) ?
       
  2246 	 "DW_EXPR_VAL_OFFSET" : (reg_rule->ru_value_type ==
       
  2247 				 DW_EXPR_VAL_EXPRESSION) ?
       
  2248 	 "DW_EXPR_VAL_EXPRESSION" : (reg_rule->ru_value_type ==
       
  2249 				     DW_EXPR_EXPRESSION) ?
       
  2250 	 "DW_EXPR_EXPRESSION" : "Unknown",
       
  2251 	 (unsigned) reg_rule->ru_value_type, (int) reg_rule->ru_is_off,
       
  2252 	 (int) reg_rule->ru_register,
       
  2253 	 (unsigned long long) reg_rule->ru_offset_or_block_len,
       
  2254 	 (unsigned long long) reg_rule->ru_block);
       
  2255     return;
       
  2256 }
       
  2257 #endif
       
  2258 
       
  2259 /* This allows consumers to set the 'initial value' so that
       
  2260    an ISA/ABI specific default can be used, dynamically,
       
  2261    at run time.  Useful for dwarfdump and non-MIPS architectures.. 
       
  2262    The value  defaults to one of
       
  2263 	DW_FRAME_SAME_VALUE or DW_FRAME_UNKNOWN_VALUE
       
  2264    but dwarfdump can dump multiple ISA/ABI objects so
       
  2265    we may want to get this set to what the ABI says is correct.
       
  2266 
       
  2267    Returns the value that was present before we changed it here.
       
  2268 */
       
  2269 
       
  2270 Dwarf_Half
       
  2271 dwarf_set_frame_rule_inital_value(Dwarf_Debug dbg, Dwarf_Half value)
       
  2272 {
       
  2273     Dwarf_Half orig = dbg->de_frame_rule_initial_value;
       
  2274 
       
  2275     dbg->de_frame_rule_initial_value = value;
       
  2276     return orig;
       
  2277 }
       
  2278 
       
  2279 /* This allows consumers to set the array size of the  reg rules
       
  2280    table so that
       
  2281    an ISA/ABI specific value can be used, dynamically,
       
  2282    at run time.  Useful for non-MIPS archtectures.
       
  2283    The value  defaults  to DW_FRAME_LAST_REG_NUM.
       
  2284    but dwarfdump can dump multiple ISA/ABI objects so
       
  2285    consumers want to get this set to what the ABI says is correct.
       
  2286 
       
  2287    Returns the value that was present before we changed it here.
       
  2288 */
       
  2289 
       
  2290 Dwarf_Half
       
  2291 dwarf_set_frame_rule_table_size(Dwarf_Debug dbg, Dwarf_Half value)
       
  2292 {
       
  2293     Dwarf_Half orig = dbg->de_frame_reg_rules_entry_count;
       
  2294 
       
  2295     dbg->de_frame_reg_rules_entry_count = value;
       
  2296     return orig;
       
  2297 }
       
  2298 
       
  2299 
       
  2300 static int
       
  2301 dwarf_initialize_fde_table(Dwarf_Debug dbg,
       
  2302 			   struct Dwarf_Frame_s *fde_table,
       
  2303 			   unsigned table_real_data_size,
       
  2304 			   Dwarf_Error * error)
       
  2305 {
       
  2306     unsigned entry_size = sizeof(struct Dwarf_Frame_s);
       
  2307 
       
  2308     fde_table->fr_loc = 0;
       
  2309     fde_table->fr_reg_count = table_real_data_size;
       
  2310     fde_table->fr_next = 0;
       
  2311 
       
  2312     fde_table->fr_reg = (struct Dwarf_Reg_Rule_s *)
       
  2313 	calloc(entry_size, table_real_data_size);
       
  2314     if (fde_table->fr_reg == 0) {
       
  2315 	_dwarf_error(dbg, error, DW_DLE_DF_ALLOC_FAIL);
       
  2316 	return (DW_DLV_ERROR);
       
  2317     }
       
  2318     return DW_DLV_OK;
       
  2319 
       
  2320 }
       
  2321 static void
       
  2322 dwarf_free_fde_table(struct Dwarf_Frame_s *fde_table)
       
  2323 {
       
  2324     free(fde_table->fr_reg);
       
  2325     fde_table->fr_reg_count = 0;
       
  2326     fde_table->fr_reg = 0;
       
  2327 }
       
  2328 
       
  2329 
       
  2330 /* Return DW_DLV_OK if we succeed. else return DW_DLV_ERROR.
       
  2331 */
       
  2332 int
       
  2333 _dwarf_frame_constructor(Dwarf_Debug dbg, void *frame)
       
  2334 {
       
  2335     struct Dwarf_Frame_s *fp = frame;
       
  2336 
       
  2337     if (!dbg) {
       
  2338 	return DW_DLV_ERROR;
       
  2339     }
       
  2340 
       
  2341     fp->fr_reg = calloc(dbg->de_frame_reg_rules_entry_count,
       
  2342 			sizeof(struct Dwarf_Reg_Rule_s));
       
  2343     if (!fp->fr_reg) {
       
  2344 	return DW_DLV_ERROR;
       
  2345     }
       
  2346     fp->fr_reg_count = dbg->de_frame_reg_rules_entry_count;
       
  2347     return DW_DLV_OK;
       
  2348 }
       
  2349 
       
  2350 void
       
  2351 _dwarf_frame_destructor(void *frame)
       
  2352 {
       
  2353     struct Dwarf_Frame_s *fp = frame;
       
  2354 
       
  2355     if (fp->fr_reg)
       
  2356 	free(fp->fr_reg);
       
  2357     fp->fr_reg = 0;
       
  2358     fp->fr_reg_count = 0;
       
  2359 }