tools/elf4rom/libs/dwarf-20071209/libdwarf/pro_frame.c
changeset 34 92d87f2e53c2
equal deleted inserted replaced
33:1af5c1be89f8 34:92d87f2e53c2
       
     1 /*
       
     2 
       
     3   Copyright (C) 2000,2004 Silicon Graphics, Inc.  All Rights Reserved.
       
     4 
       
     5   This program is free software; you can redistribute it and/or modify it
       
     6   under the terms of version 2.1 of the GNU Lesser General Public License 
       
     7   as published by the Free Software Foundation.
       
     8 
       
     9   This program is distributed in the hope that it would be useful, but
       
    10   WITHOUT ANY WARRANTY; without even the implied warranty of
       
    11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  
       
    12 
       
    13   Further, this software is distributed without any warranty that it is
       
    14   free of the rightful claim of any third person regarding infringement 
       
    15   or the like.  Any license provided herein, whether implied or 
       
    16   otherwise, applies only to this software file.  Patent licenses, if
       
    17   any, provided herein do not apply to combinations of this program with 
       
    18   other software, or any other product whatsoever.  
       
    19 
       
    20   You should have received a copy of the GNU Lesser General Public 
       
    21   License along with this program; if not, write the Free Software 
       
    22   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
       
    23   USA.
       
    24 
       
    25   Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
       
    26   Mountain View, CA 94043, or:
       
    27 
       
    28   http://www.sgi.com
       
    29 
       
    30   For further information regarding this notice, see:
       
    31 
       
    32   http://oss.sgi.com/projects/GenInfo/NoticeExplan
       
    33 
       
    34 */
       
    35 
       
    36 
       
    37 
       
    38 #include "config.h"
       
    39 #include "libdwarfdefs.h"
       
    40 #include <stdio.h>
       
    41 #include <string.h>
       
    42 #include <limits.h>
       
    43 #include "pro_incl.h"
       
    44 #include "pro_frame.h"
       
    45 
       
    46 static void _dwarf_pro_add_to_fde(Dwarf_P_Fde fde,
       
    47 				  Dwarf_P_Frame_Pgm inst);
       
    48 
       
    49 /*-------------------------------------------------------------------------
       
    50 	This functions adds a cie struct to the debug pointer. Its in the
       
    51 	form of a linked list.
       
    52 	augmenter: string reps augmentation (implementation defined)
       
    53 	code_align: alignment of code
       
    54 	data_align: alignment of data
       
    55 	init_bytes: byts having initial instructions
       
    56 	init_n_bytes: number of bytes of initial instructions
       
    57 --------------------------------------------------------------------------*/
       
    58 Dwarf_Unsigned
       
    59 dwarf_add_frame_cie(Dwarf_P_Debug dbg,
       
    60 		    char *augmenter,
       
    61 		    Dwarf_Small code_align,
       
    62 		    Dwarf_Small data_align,
       
    63 		    Dwarf_Small return_reg,
       
    64 		    Dwarf_Ptr init_bytes,
       
    65 		    Dwarf_Unsigned init_n_bytes, Dwarf_Error * error)
       
    66 {
       
    67     Dwarf_P_Cie curcie;
       
    68 
       
    69     if (dbg->de_frame_cies == NULL) {
       
    70 	dbg->de_frame_cies = (Dwarf_P_Cie)
       
    71 	    _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Cie_s));
       
    72 	if (dbg->de_frame_cies == NULL) {
       
    73 	    DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_ALLOC, DW_DLV_NOCOUNT);
       
    74 	}
       
    75 	curcie = dbg->de_frame_cies;
       
    76 	dbg->de_n_cie = 1;
       
    77 	dbg->de_last_cie = curcie;
       
    78     } else {
       
    79 	curcie = dbg->de_last_cie;
       
    80 	curcie->cie_next = (Dwarf_P_Cie)
       
    81 	    _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Cie_s));
       
    82 	if (curcie->cie_next == NULL) {
       
    83 	    DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_ALLOC, DW_DLV_NOCOUNT);
       
    84 	}
       
    85 	curcie = curcie->cie_next;
       
    86 	dbg->de_n_cie++;
       
    87 	dbg->de_last_cie = curcie;
       
    88     }
       
    89     curcie->cie_version = DW_CIE_VERSION;
       
    90     curcie->cie_aug = augmenter;
       
    91     curcie->cie_code_align = code_align;
       
    92     curcie->cie_data_align = data_align;
       
    93     curcie->cie_ret_reg = return_reg;
       
    94     curcie->cie_inst = (char *) init_bytes;
       
    95     curcie->cie_inst_bytes = (long) init_n_bytes;
       
    96     curcie->cie_next = NULL;
       
    97     return dbg->de_n_cie;
       
    98 }
       
    99 
       
   100 
       
   101 /*-------------------------------------------------------------------------
       
   102 	This functions adds a fde struct to the debug pointer. Its in the
       
   103 	form of a linked list.
       
   104 	die: subprogram/function die corresponding to this fde
       
   105 	cie: cie referred to by this fde, obtained from call to 
       
   106 	    add_frame_cie() routine.
       
   107 	virt_addr: beginning address
       
   108 	code_len: length of code reps by the fde
       
   109 --------------------------------------------------------------------------*/
       
   110  /*ARGSUSED*/			/* pretend all args used */
       
   111     Dwarf_Unsigned
       
   112 dwarf_add_frame_fde(Dwarf_P_Debug dbg,
       
   113 		    Dwarf_P_Fde fde,
       
   114 		    Dwarf_P_Die die,
       
   115 		    Dwarf_Unsigned cie,
       
   116 		    Dwarf_Unsigned virt_addr,
       
   117 		    Dwarf_Unsigned code_len,
       
   118 		    Dwarf_Unsigned symidx, Dwarf_Error * error)
       
   119 {
       
   120     return dwarf_add_frame_fde_b(dbg, fde, die, cie, virt_addr,
       
   121 				 code_len, symidx, 0, 0, error);
       
   122 }
       
   123 
       
   124 /*ARGSUSED10*/
       
   125 Dwarf_Unsigned
       
   126 dwarf_add_frame_fde_b(Dwarf_P_Debug dbg,
       
   127 		      Dwarf_P_Fde fde,
       
   128 		      Dwarf_P_Die die,
       
   129 		      Dwarf_Unsigned cie,
       
   130 		      Dwarf_Unsigned virt_addr,
       
   131 		      Dwarf_Unsigned code_len,
       
   132 		      Dwarf_Unsigned symidx,
       
   133 		      Dwarf_Unsigned symidx_of_end,
       
   134 		      Dwarf_Addr offset_from_end_sym,
       
   135 		      Dwarf_Error * error)
       
   136 {
       
   137     Dwarf_P_Fde curfde;
       
   138 
       
   139     fde->fde_die = die;
       
   140     fde->fde_cie = (long) cie;
       
   141     fde->fde_initloc = virt_addr;
       
   142     fde->fde_r_symidx = symidx;
       
   143     fde->fde_addr_range = code_len;
       
   144     fde->fde_offset_into_exception_tables = DW_DLX_NO_EH_OFFSET;
       
   145     fde->fde_exception_table_symbol = 0;
       
   146     fde->fde_end_symbol_offset = offset_from_end_sym;
       
   147     fde->fde_end_symbol = symidx_of_end;
       
   148     fde->fde_dbg = dbg;
       
   149 
       
   150     curfde = dbg->de_last_fde;
       
   151     if (curfde == NULL) {
       
   152 	dbg->de_frame_fdes = fde;
       
   153 	dbg->de_last_fde = fde;
       
   154 	dbg->de_n_fde = 1;
       
   155     } else {
       
   156 	curfde->fde_next = fde;
       
   157 	dbg->de_last_fde = fde;
       
   158 	dbg->de_n_fde++;
       
   159     }
       
   160     return dbg->de_n_fde;
       
   161 }
       
   162 
       
   163 /*-------------------------------------------------------------------------
       
   164 	This functions adds information to an fde. The fde is
       
   165 	linked into the linked list of fde's maintained in the Dwarf_P_Debug
       
   166 	structure.
       
   167 	dbg: The debug descriptor.
       
   168 	fde: The fde to be added.
       
   169 	die: subprogram/function die corresponding to this fde
       
   170 	cie: cie referred to by this fde, obtained from call to 
       
   171 	    add_frame_cie() routine.
       
   172 	virt_addr: beginning address
       
   173 	code_len: length of code reps by the fde
       
   174 	symidx: The symbol id of the symbol wrt to which relocation needs
       
   175 		to be performed for 'virt_addr'.
       
   176 	offset_into_exception_tables: The start of exception tables for
       
   177 		this function (indicated as an offset into the exception
       
   178 		tables). A value of -1 indicates that there is no exception
       
   179 		table entries associated with this function.
       
   180 	exception_table_symbol: The symbol id of the section for exception
       
   181 		tables wrt to which the offset_into_exception_tables will
       
   182 		be relocated.
       
   183 --------------------------------------------------------------------------*/
       
   184 Dwarf_Unsigned
       
   185 dwarf_add_frame_info(Dwarf_P_Debug dbg,
       
   186 		     Dwarf_P_Fde fde,
       
   187 		     Dwarf_P_Die die,
       
   188 		     Dwarf_Unsigned cie,
       
   189 		     Dwarf_Unsigned virt_addr,
       
   190 		     Dwarf_Unsigned code_len,
       
   191 		     Dwarf_Unsigned symidx,
       
   192 		     Dwarf_Signed offset_into_exception_tables,
       
   193 		     Dwarf_Unsigned exception_table_symbol,
       
   194 		     Dwarf_Error * error)
       
   195 {
       
   196 
       
   197     return dwarf_add_frame_info_b(dbg, fde, die, cie, virt_addr,
       
   198 				  code_len, symidx,
       
   199 				  /* end_symbol */ 0,
       
   200 				  /* offset_from_end */ 0,
       
   201 				  offset_into_exception_tables,
       
   202 				  exception_table_symbol, error);
       
   203 
       
   204 }
       
   205 
       
   206  /*ARGSUSED*/			/* pretend all args used */
       
   207     Dwarf_Unsigned
       
   208 dwarf_add_frame_info_b(Dwarf_P_Debug dbg,
       
   209 		       Dwarf_P_Fde fde,
       
   210 		       Dwarf_P_Die die,
       
   211 		       Dwarf_Unsigned cie,
       
   212 		       Dwarf_Unsigned virt_addr,
       
   213 		       Dwarf_Unsigned code_len,
       
   214 		       Dwarf_Unsigned symidx,
       
   215 		       Dwarf_Unsigned end_symidx,
       
   216 		       Dwarf_Unsigned offset_from_end_symbol,
       
   217 		       Dwarf_Signed offset_into_exception_tables,
       
   218 		       Dwarf_Unsigned exception_table_symbol,
       
   219 		       Dwarf_Error * error)
       
   220 {
       
   221     Dwarf_P_Fde curfde;
       
   222 
       
   223     fde->fde_die = die;
       
   224     fde->fde_cie = (long) cie;
       
   225     fde->fde_initloc = virt_addr;
       
   226     fde->fde_r_symidx = symidx;
       
   227     fde->fde_addr_range = code_len;
       
   228     fde->fde_offset_into_exception_tables =
       
   229 	offset_into_exception_tables;
       
   230     fde->fde_exception_table_symbol = exception_table_symbol;
       
   231     fde->fde_end_symbol_offset = offset_from_end_symbol;
       
   232     fde->fde_end_symbol = end_symidx;
       
   233     fde->fde_dbg = dbg;
       
   234 
       
   235     curfde = dbg->de_last_fde;
       
   236     if (curfde == NULL) {
       
   237 	dbg->de_frame_fdes = fde;
       
   238 	dbg->de_last_fde = fde;
       
   239 	dbg->de_n_fde = 1;
       
   240     } else {
       
   241 	curfde->fde_next = fde;
       
   242 	dbg->de_last_fde = fde;
       
   243 	dbg->de_n_fde++;
       
   244     }
       
   245     return dbg->de_n_fde;
       
   246 }
       
   247 
       
   248 
       
   249 /*-------------------------------------------------------------------
       
   250 	Create a new fde 
       
   251 ---------------------------------------------------------------------*/
       
   252 Dwarf_P_Fde
       
   253 dwarf_new_fde(Dwarf_P_Debug dbg, Dwarf_Error * error)
       
   254 {
       
   255     Dwarf_P_Fde fde;
       
   256 
       
   257     fde = (Dwarf_P_Fde)
       
   258 	_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Fde_s));
       
   259     if (fde == NULL) {
       
   260 	DWARF_P_DBG_ERROR(dbg, DW_DLE_FDE_ALLOC,
       
   261 			  (Dwarf_P_Fde) DW_DLV_BADADDR);
       
   262     }
       
   263     fde->fde_next = NULL;
       
   264     fde->fde_inst = NULL;
       
   265     fde->fde_n_inst = 0;
       
   266     fde->fde_n_bytes = 0;
       
   267     fde->fde_last_inst = NULL;
       
   268     fde->fde_uwordb_size = dbg->de_offset_size;
       
   269     return fde;
       
   270 }
       
   271 
       
   272 /*------------------------------------------------------------------------
       
   273 	Add cfe_offset instruction to fde
       
   274 -------------------------------------------------------------------------*/
       
   275 Dwarf_P_Fde
       
   276 dwarf_fde_cfa_offset(Dwarf_P_Fde fde,
       
   277 		     Dwarf_Unsigned reg,
       
   278 		     Dwarf_Signed offset, Dwarf_Error * error)
       
   279 {
       
   280     Dwarf_Ubyte opc, regno;
       
   281     char *ptr;
       
   282     Dwarf_P_Frame_Pgm curinst;
       
   283     int nbytes;
       
   284     int res;
       
   285     char buff1[ENCODE_SPACE_NEEDED];
       
   286     Dwarf_P_Debug dbg = fde->fde_dbg;
       
   287 
       
   288     curinst = (Dwarf_P_Frame_Pgm)
       
   289 	_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Frame_Pgm_s));
       
   290     if (curinst == NULL) {
       
   291 	DWARF_P_DBG_ERROR(dbg, DW_DLE_FPGM_ALLOC,
       
   292 			  (Dwarf_P_Fde) DW_DLV_BADADDR);
       
   293     }
       
   294     opc = DW_CFA_offset;
       
   295     regno = reg;
       
   296     if (regno & 0xc0) {
       
   297 	DWARF_P_DBG_ERROR(dbg, DW_DLE_REGNO_OVFL,
       
   298 			  (Dwarf_P_Fde) DW_DLV_BADADDR);
       
   299     }
       
   300     opc = opc | regno;		/* lower 6 bits are register number */
       
   301     curinst->dfp_opcode = opc;
       
   302     res = _dwarf_pro_encode_leb128_nm(offset, &nbytes,
       
   303 				      buff1, sizeof(buff1));
       
   304     if (res != DW_DLV_OK) {
       
   305 	_dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
       
   306 	return ((Dwarf_P_Fde) DW_DLV_BADADDR);
       
   307     }
       
   308     ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes);
       
   309     if (ptr == NULL) {
       
   310 	_dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
       
   311 	return ((Dwarf_P_Fde) DW_DLV_BADADDR);
       
   312     }
       
   313     memcpy(ptr, buff1, nbytes);
       
   314 
       
   315     curinst->dfp_args = ptr;
       
   316     curinst->dfp_nbytes = nbytes;
       
   317     curinst->dfp_next = NULL;
       
   318 
       
   319     _dwarf_pro_add_to_fde(fde, curinst);
       
   320     return fde;
       
   321 }
       
   322 
       
   323 /*
       
   324     Generic routine to add opcode to fde instructions. val1 and
       
   325     val2 are parameters whose interpretation depends on the 'op'.
       
   326 
       
   327     This does not work properly for  DW_DLC_SYMBOLIC_RELOCATIONS
       
   328     for DW_CFA_set_loc or DW_DVA_advance_loc* 'op', as
       
   329     these ops normally are addresses or (DW_CFA_set_loc) 
       
   330     or code lengths (DW_DVA_advance_loc*) and such must be
       
   331     represented with relocations and symbol indices for
       
   332     DW_DLC_SYMBOLIC_RELOCATIONS.
       
   333 
       
   334     This does not treat all DW_CFA instructions and
       
   335     currently excludes DWARF3 additions.
       
   336 
       
   337 */
       
   338 Dwarf_P_Fde
       
   339 dwarf_add_fde_inst(Dwarf_P_Fde fde,
       
   340 		   Dwarf_Small op,
       
   341 		   Dwarf_Unsigned val1,
       
   342 		   Dwarf_Unsigned val2, Dwarf_Error * error)
       
   343 {
       
   344     Dwarf_P_Frame_Pgm curinst;
       
   345     int nbytes, nbytes1, nbytes2;
       
   346     Dwarf_Ubyte db;
       
   347     Dwarf_Half dh;
       
   348     Dwarf_Word dw;
       
   349     Dwarf_Unsigned du;
       
   350     char *ptr;
       
   351     int res;
       
   352     char buff1[ENCODE_SPACE_NEEDED];
       
   353     char buff2[ENCODE_SPACE_NEEDED];
       
   354     Dwarf_P_Debug dbg = fde->fde_dbg;
       
   355 
       
   356 
       
   357     nbytes = 0;
       
   358     ptr = NULL;
       
   359     curinst = (Dwarf_P_Frame_Pgm)
       
   360 	_dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Frame_Pgm_s));
       
   361     if (curinst == NULL) {
       
   362 	_dwarf_p_error(dbg, error, DW_DLE_FPGM_ALLOC);
       
   363 	return ((Dwarf_P_Fde) DW_DLV_BADADDR);
       
   364     }
       
   365 
       
   366     switch (op) {
       
   367 
       
   368     case DW_CFA_advance_loc:
       
   369 	if (val1 <= 0x3f) {
       
   370 	    db = val1;
       
   371 	    op |= db;
       
   372 	}
       
   373 	/* test not portable FIX */
       
   374 	else if (val1 <= UCHAR_MAX) {
       
   375 	    op = DW_CFA_advance_loc1;
       
   376 	    db = val1;
       
   377 	    ptr = (char *) _dwarf_p_get_alloc(dbg, 1);
       
   378 	    if (ptr == NULL) {
       
   379 		_dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
       
   380 		return ((Dwarf_P_Fde) DW_DLV_BADADDR);
       
   381 	    }
       
   382 	    memcpy((void *) ptr, (const void *) &db, 1);
       
   383 	    nbytes = 1;
       
   384 	}
       
   385 	/* test not portable FIX */
       
   386 	else if (val1 <= USHRT_MAX) {
       
   387 	    op = DW_CFA_advance_loc2;
       
   388 	    dh = val1;
       
   389 	    ptr = (char *) _dwarf_p_get_alloc(dbg, 2);
       
   390 	    if (ptr == NULL) {
       
   391 		_dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
       
   392 		return ((Dwarf_P_Fde) DW_DLV_BADADDR);
       
   393 	    }
       
   394 	    memcpy((void *) ptr, (const void *) &dh, 2);
       
   395 	    nbytes = 2;
       
   396 	}
       
   397 	/* test not portable FIX */
       
   398 	else if (val1 <= ULONG_MAX) {
       
   399 	    op = DW_CFA_advance_loc4;
       
   400 	    dw = (Dwarf_Word) val1;
       
   401 	    ptr = (char *) _dwarf_p_get_alloc(dbg, 4);
       
   402 	    if (ptr == NULL) {
       
   403 		_dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
       
   404 		return ((Dwarf_P_Fde) DW_DLV_BADADDR);
       
   405 	    }
       
   406 	    memcpy((void *) ptr, (const void *) &dw, 4);
       
   407 	    nbytes = 4;
       
   408 	} else {
       
   409 	    op = DW_CFA_MIPS_advance_loc8;
       
   410 	    du = val1;
       
   411 	    ptr =
       
   412 		(char *) _dwarf_p_get_alloc(dbg,
       
   413 					    sizeof(Dwarf_Unsigned));
       
   414 	    if (ptr == NULL) {
       
   415 		_dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
       
   416 		return ((Dwarf_P_Fde) DW_DLV_BADADDR);
       
   417 	    }
       
   418 	    memcpy((void *) ptr, (const void *) &du, 8);
       
   419 	    nbytes = 8;
       
   420 	}
       
   421 	break;
       
   422 
       
   423     case DW_CFA_offset:
       
   424 	if (val1 <= MAX_6_BIT_VALUE) {
       
   425 	    db = val1;
       
   426 	    op |= db;
       
   427 	    res = _dwarf_pro_encode_leb128_nm(val2, &nbytes,
       
   428 					      buff1, sizeof(buff1));
       
   429 	    if (res != DW_DLV_OK) {
       
   430 		_dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
       
   431 		return ((Dwarf_P_Fde) DW_DLV_BADADDR);
       
   432 	    }
       
   433 	    ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes);
       
   434 	    if (ptr == NULL) {
       
   435 		_dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
       
   436 		return ((Dwarf_P_Fde) DW_DLV_BADADDR);
       
   437 	    }
       
   438 	    memcpy(ptr, buff1, nbytes);
       
   439 
       
   440 	} else {
       
   441 	    op = DW_CFA_offset_extended;
       
   442 
       
   443 	    res = _dwarf_pro_encode_leb128_nm(val1, &nbytes1,
       
   444 					      buff1, sizeof(buff1));
       
   445 	    if (res != DW_DLV_OK) {
       
   446 		_dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
       
   447 		return ((Dwarf_P_Fde) DW_DLV_BADADDR);
       
   448 	    }
       
   449 	    res = _dwarf_pro_encode_leb128_nm(val2, &nbytes2,
       
   450 					      buff2, sizeof(buff2));
       
   451 	    if (res != DW_DLV_OK) {
       
   452 		_dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
       
   453 		return ((Dwarf_P_Fde) DW_DLV_BADADDR);
       
   454 	    }
       
   455 	    ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes1 + nbytes2);
       
   456 	    if (ptr == NULL) {
       
   457 		_dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
       
   458 		return ((Dwarf_P_Fde) DW_DLV_BADADDR);
       
   459 	    }
       
   460 	    memcpy(ptr, buff1, nbytes1);
       
   461 	    memcpy(ptr + nbytes1, buff2, nbytes2);
       
   462 	    nbytes = nbytes1 + nbytes2;
       
   463 	}
       
   464 	break;
       
   465 
       
   466     case DW_CFA_undefined:
       
   467     case DW_CFA_same_value:
       
   468 	res = _dwarf_pro_encode_leb128_nm(val1, &nbytes,
       
   469 					  buff1, sizeof(buff1));
       
   470 	if (res != DW_DLV_OK) {
       
   471 	    _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
       
   472 	    return ((Dwarf_P_Fde) DW_DLV_BADADDR);
       
   473 	}
       
   474 	ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes);
       
   475 	if (ptr == NULL) {
       
   476 	    _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
       
   477 	    return ((Dwarf_P_Fde) DW_DLV_BADADDR);
       
   478 	}
       
   479 	memcpy(ptr, buff1, nbytes);
       
   480 	break;
       
   481 
       
   482     case DW_CFA_register:
       
   483     case DW_CFA_def_cfa:
       
   484 	res = _dwarf_pro_encode_leb128_nm(val1, &nbytes1,
       
   485 					  buff1, sizeof(buff1));
       
   486 	if (res != DW_DLV_OK) {
       
   487 	    _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
       
   488 	    return ((Dwarf_P_Fde) DW_DLV_BADADDR);
       
   489 	}
       
   490 
       
   491 	res = _dwarf_pro_encode_leb128_nm(val2, &nbytes2,
       
   492 					  buff2, sizeof(buff2));
       
   493 	if (res != DW_DLV_OK) {
       
   494 	    _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
       
   495 	    return ((Dwarf_P_Fde) DW_DLV_BADADDR);
       
   496 	}
       
   497 
       
   498 	ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes1 + nbytes2);
       
   499 	if (ptr == NULL) {
       
   500 	    _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
       
   501 	    return ((Dwarf_P_Fde) DW_DLV_BADADDR);
       
   502 	}
       
   503 	memcpy(ptr, buff1, nbytes1);
       
   504 	memcpy(ptr + nbytes1, buff2, nbytes2);
       
   505 	nbytes = nbytes1 + nbytes2;
       
   506 	break;
       
   507 
       
   508     case DW_CFA_def_cfa_register:
       
   509     case DW_CFA_def_cfa_offset:
       
   510 	res = _dwarf_pro_encode_leb128_nm(val1, &nbytes,
       
   511 					  buff1, sizeof(buff1));
       
   512 	if (res != DW_DLV_OK) {
       
   513 	    _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
       
   514 	    return ((Dwarf_P_Fde) DW_DLV_BADADDR);
       
   515 	}
       
   516 	ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes);
       
   517 	if (ptr == NULL) {
       
   518 	    _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC);
       
   519 	    return ((Dwarf_P_Fde) DW_DLV_BADADDR);
       
   520 	}
       
   521 	memcpy(ptr, buff1, nbytes);
       
   522 	break;
       
   523 
       
   524     default:
       
   525 	/* This is wrong. We are just ignoring
       
   526            instructions we don't yet handle. FIXME. */
       
   527 	break;
       
   528     }
       
   529 
       
   530     curinst->dfp_opcode = op;
       
   531     curinst->dfp_args = ptr;
       
   532     curinst->dfp_nbytes = nbytes;
       
   533     curinst->dfp_next = NULL;
       
   534 
       
   535     _dwarf_pro_add_to_fde(fde, curinst);
       
   536     return fde;
       
   537 }
       
   538 
       
   539 
       
   540 /*------------------------------------------------------------------------
       
   541 	instructions are added to fde in the form of a linked
       
   542 	list. This function manages the linked list
       
   543 -------------------------------------------------------------------------*/
       
   544 void
       
   545 _dwarf_pro_add_to_fde(Dwarf_P_Fde fde, Dwarf_P_Frame_Pgm curinst)
       
   546 {
       
   547     if (fde->fde_last_inst) {
       
   548 	fde->fde_last_inst->dfp_next = curinst;
       
   549 	fde->fde_last_inst = curinst;
       
   550 	fde->fde_n_inst++;
       
   551 	fde->fde_n_bytes +=
       
   552 	    (long) (curinst->dfp_nbytes + sizeof(Dwarf_Ubyte));
       
   553     } else {
       
   554 	fde->fde_last_inst = curinst;
       
   555 	fde->fde_inst = curinst;
       
   556 	fde->fde_n_inst = 1;
       
   557 	fde->fde_n_bytes =
       
   558 	    (long) (curinst->dfp_nbytes + sizeof(Dwarf_Ubyte));
       
   559     }
       
   560 }