tools/elf4rom/libs/dwarf-20071209/libdwarf/dwarf_frame2.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 	This  implements _dwarf_get_fde_list_internal()
       
    45         and related helper functions for reading cie/fde data.
       
    46 */
       
    47 
       
    48 
       
    49 
       
    50 #include "config.h"
       
    51 #include "dwarf_incl.h"
       
    52 #include <stdio.h>
       
    53 #include <stdlib.h>
       
    54 #include "dwarf_frame.h"
       
    55 #include "dwarf_arange.h"	/* using Arange as a way to build a
       
    56 				   list */
       
    57 
       
    58 
       
    59 static int dwarf_find_existing_cie_ptr(Dwarf_Small * cie_ptr,
       
    60 				       Dwarf_Cie cur_cie_ptr,
       
    61 				       Dwarf_Cie * cie_ptr_to_use_out,
       
    62 				       Dwarf_Cie head_cie_ptr);
       
    63 static void dealloc_fde_cie_list_internal(Dwarf_Fde head_fde_ptr,
       
    64 					  Dwarf_Cie head_cie_ptr);
       
    65 static int dwarf_create_cie_from_start(Dwarf_Debug dbg,
       
    66 				       Dwarf_Small * cie_ptr_val,
       
    67 				       Dwarf_Small * section_ptr,
       
    68 				       Dwarf_Unsigned section_index,
       
    69 				       Dwarf_Unsigned section_length,
       
    70 				       Dwarf_Small * frame_ptr_end,
       
    71 				       Dwarf_Unsigned cie_id_value,
       
    72 				       Dwarf_Unsigned cie_count,
       
    73 				       int use_gnu_cie_calc,
       
    74 				       Dwarf_Cie * cie_ptr_to_use_out,
       
    75 				       Dwarf_Error * error);
       
    76 
       
    77 static Dwarf_Small *get_cieptr_given_offset(Dwarf_Unsigned cie_id_value,
       
    78 					    int use_gnu_cie_calc,
       
    79 					    Dwarf_Small * section_ptr,
       
    80 					    Dwarf_Small * cie_id_addr);
       
    81 static int get_gcc_eh_augmentation(Dwarf_Debug dbg,
       
    82 				   Dwarf_Small * frame_ptr,
       
    83 				   unsigned long
       
    84 				   *size_of_augmentation_data,
       
    85 				   enum Dwarf_augmentation_type augtype,
       
    86 				   Dwarf_Small * section_pointer,
       
    87 				   Dwarf_Small * fde_eh_encoding_out,
       
    88 				   char *augmentation);
       
    89 
       
    90 static int
       
    91   gnu_aug_encodings(Dwarf_Debug dbg, char *augmentation,
       
    92 		    Dwarf_Small * aug_data, Dwarf_Unsigned aug_data_len,
       
    93 		    unsigned char *pers_hand_enc_out,
       
    94 		    unsigned char *lsda_enc_out,
       
    95 		    unsigned char *fde_begin_enc_out,
       
    96 		    Dwarf_Addr * gnu_pers_addr_out);
       
    97 
       
    98 
       
    99 static int read_encoded_ptr(Dwarf_Debug dbg,
       
   100 			    Dwarf_Small * section_pointer,
       
   101 			    Dwarf_Small * input_field,
       
   102 			    int gnu_encoding,
       
   103 			    Dwarf_Unsigned * addr,
       
   104 			    Dwarf_Small ** input_field_out);
       
   105 
       
   106 
       
   107 
       
   108 static int qsort_compare(const void *elem1, const void *elem2);
       
   109 
       
   110 
       
   111 /* Adds 'newone' to the end of the list starting at 'head'
       
   112    and makes the new one 'cur'rent. */
       
   113 static void
       
   114 chain_up_fde(Dwarf_Fde newone, Dwarf_Fde * head, Dwarf_Fde * cur)
       
   115 {
       
   116     if (*head == NULL)
       
   117 	*head = newone;
       
   118     else {
       
   119 	(*cur)->fd_next = newone;
       
   120     }
       
   121     *cur = newone;
       
   122 
       
   123 }
       
   124 
       
   125 /* Adds 'newone' to the end of the list starting at 'head'
       
   126    and makes the new one 'cur'rent. */
       
   127 static void
       
   128 chain_up_cie(Dwarf_Cie newone, Dwarf_Cie * head, Dwarf_Cie * cur)
       
   129 {
       
   130     if (*head == NULL) {
       
   131 	*head = newone;
       
   132     } else {
       
   133 	(*cur)->ci_next = newone;
       
   134     }
       
   135     *cur = newone;
       
   136 }
       
   137 
       
   138 #if 0
       
   139 /* For debugging only. */
       
   140 static void
       
   141 print_prefix(struct cie_fde_prefix_s *prefix, int line)
       
   142 {
       
   143     printf("prefix-print, prefix at 0x%lx, line %d\n",
       
   144 	   (long) prefix, line);
       
   145     printf("  start addr 0x%lx after prefix 0x%lx\n",
       
   146 	   (long) prefix->cf_start_addr,
       
   147 	   (long) prefix->cf_addr_after_prefix);
       
   148     printf("  length 0x%llx, len size %d ext size %d\n", (long long)
       
   149 	   (unsigned long long) prefix->cf_length,
       
   150 	   prefix->cf_local_length_size,
       
   151 	   prefix->cf_local_extension_size);
       
   152     printf("  cie_id 0x%llx cie_id  cie_id_addr 0x%lx\n",
       
   153 	   (unsigned long long) prefix->cf_cie_id,
       
   154 	   (long) prefix->cf_cie_id_addr);
       
   155     printf
       
   156 	("  sec ptr 0x%lx sec index %lld sec len 0x%llx sec past end 0x%lx\n",
       
   157 	 (long) prefix->cf_section_ptr,
       
   158 	 (long long) prefix->cf_section_index,
       
   159 	 (unsigned long long) prefix->cf_section_length,
       
   160 	 (long) prefix->cf_section_ptr + prefix->cf_section_length);
       
   161 }
       
   162 #endif
       
   163 
       
   164 
       
   165 
       
   166 /* Internal function called from various places to create
       
   167    lists of CIEs and FDEs.  Not directly called
       
   168    by consumer code */
       
   169 int
       
   170 _dwarf_get_fde_list_internal(Dwarf_Debug dbg, Dwarf_Cie ** cie_data,
       
   171 			     Dwarf_Signed * cie_element_count,
       
   172 			     Dwarf_Fde ** fde_data,
       
   173 			     Dwarf_Signed * fde_element_count,
       
   174 			     Dwarf_Small * section_ptr,
       
   175 			     Dwarf_Unsigned section_index,
       
   176 			     Dwarf_Unsigned section_length,
       
   177 			     Dwarf_Unsigned cie_id_value,
       
   178 			     int use_gnu_cie_calc, Dwarf_Error * error)
       
   179 {
       
   180     /* Scans the debug_frame section. */
       
   181     Dwarf_Small *frame_ptr = section_ptr;
       
   182     Dwarf_Small *frame_ptr_end = section_ptr + section_length;
       
   183 
       
   184 
       
   185 
       
   186     /* 
       
   187        New_cie points to the Cie being read, and head_cie_ptr and
       
   188        cur_cie_ptr are used for chaining them up in sequence. 
       
   189        In case cie's are reused aggressively we need tail_cie_ptr
       
   190        to add to the chain.  If we re-use an early cie
       
   191        later on, that does not mean we chain a new cie to the early one,
       
   192        we always chain it to the tail.  */
       
   193     Dwarf_Cie head_cie_ptr = NULL;
       
   194     Dwarf_Cie cur_cie_ptr = NULL;
       
   195     Dwarf_Cie tail_cie_ptr = NULL;
       
   196     Dwarf_Word cie_count = 0;
       
   197 
       
   198     /* 
       
   199        Points to a list of contiguous pointers to Dwarf_Cie structures. 
       
   200      */
       
   201     Dwarf_Cie *cie_list_ptr = 0;
       
   202 
       
   203 
       
   204     /* 
       
   205        New_fde points to the Fde being created, and head_fde_ptr and
       
   206        cur_fde_ptr are used to chain them up. */
       
   207     Dwarf_Fde head_fde_ptr = NULL;
       
   208     Dwarf_Fde cur_fde_ptr = NULL;
       
   209     Dwarf_Word fde_count = 0;
       
   210 
       
   211     /* 
       
   212        Points to a list of contiguous pointers to Dwarf_Fde structures. 
       
   213      */
       
   214     Dwarf_Fde *fde_list_ptr = NULL;
       
   215 
       
   216     Dwarf_Word i = 0;
       
   217     int res = 0;
       
   218 
       
   219     if (frame_ptr == 0) {
       
   220 	return DW_DLV_NO_ENTRY;
       
   221     }
       
   222 
       
   223     /* We create the fde and cie arrays. Processing each CIE as we come 
       
   224        to it or as an FDE refers to it.  We cannot process 'late' CIEs
       
   225        late as GNU .eh_frame complexities mean we need the whole CIE
       
   226        before we can process the FDE correctly. */
       
   227     while (frame_ptr < frame_ptr_end) {
       
   228 
       
   229 	struct cie_fde_prefix_s prefix;
       
   230 
       
   231 	/* First read in the 'common prefix' to figure out what we are
       
   232 	   to do with this entry. */
       
   233 	memset(&prefix, 0, sizeof(prefix));
       
   234 	res = dwarf_read_cie_fde_prefix(dbg,
       
   235 					frame_ptr, section_ptr,
       
   236 					section_index,
       
   237 					section_length, &prefix, error);
       
   238 	if (res == DW_DLV_ERROR) {
       
   239 	    dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr);
       
   240 	    return res;
       
   241 	}
       
   242 	if (res == DW_DLV_NO_ENTRY)
       
   243 	    break;
       
   244 	frame_ptr = prefix.cf_addr_after_prefix;
       
   245 	if (frame_ptr >= frame_ptr_end) {
       
   246 	    dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr);
       
   247 	    _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);
       
   248 	    return DW_DLV_ERROR;
       
   249 
       
   250 	}
       
   251 
       
   252 	if (prefix.cf_cie_id == cie_id_value) {
       
   253 	    /* This is a CIE.  */
       
   254 	    Dwarf_Cie cie_ptr_to_use = 0;
       
   255 
       
   256 	    int res = dwarf_find_existing_cie_ptr(prefix.cf_start_addr,
       
   257 						  cur_cie_ptr,
       
   258 						  &cie_ptr_to_use,
       
   259 						  head_cie_ptr);
       
   260 
       
   261 	    if (res == DW_DLV_OK) {
       
   262 		cur_cie_ptr = cie_ptr_to_use;
       
   263 		/* Ok. Seen already. */
       
   264 	    } else if (res == DW_DLV_NO_ENTRY) {
       
   265 		/* CIE before its FDE in this case. */
       
   266 		res = dwarf_create_cie_from_after_start(dbg,
       
   267 							&prefix,
       
   268 							section_ptr,
       
   269 							frame_ptr,
       
   270 							cie_count,
       
   271 							use_gnu_cie_calc,
       
   272 							&cie_ptr_to_use,
       
   273 							error);
       
   274 		/* ASSERT: res==DW_DLV_NO_ENTRY impossible. */
       
   275 		if (res == DW_DLV_ERROR) {
       
   276 		    dealloc_fde_cie_list_internal(head_fde_ptr,
       
   277 						  head_cie_ptr);
       
   278 		    return res;
       
   279 		}
       
   280 		/* ASSERT res != DW_DLV_NO_ENTRY */
       
   281 		cie_count++;
       
   282 		chain_up_cie(cie_ptr_to_use, &head_cie_ptr,
       
   283 			     &tail_cie_ptr);
       
   284                 cur_cie_ptr = tail_cie_ptr;
       
   285 	    } else {		/* res == DW_DLV_ERROR */
       
   286 
       
   287 		dealloc_fde_cie_list_internal(head_fde_ptr,
       
   288 					      head_cie_ptr);
       
   289 		return res;
       
   290 	    }
       
   291 	    frame_ptr = cie_ptr_to_use->ci_cie_start +
       
   292 		cie_ptr_to_use->ci_length +
       
   293 		cie_ptr_to_use->ci_length_size +
       
   294 		cie_ptr_to_use->ci_extension_size;
       
   295 	    continue;
       
   296 	} else {
       
   297 	    /* this is an FDE, Frame Description Entry, see the Dwarf
       
   298 	       Spec, section 6.4.1 */
       
   299 	    int res = 0;
       
   300 	    Dwarf_Cie cie_ptr_to_use = 0;
       
   301 	    Dwarf_Fde fde_ptr_to_use = 0;
       
   302 
       
   303 	    /* Do not call this twice on one prefix, as
       
   304 	       prefix.cf_cie_id_addr is altered as a side effect. */
       
   305 	    Dwarf_Small *cieptr_val =
       
   306 		get_cieptr_given_offset(prefix.cf_cie_id,
       
   307 					use_gnu_cie_calc,
       
   308 					section_ptr,
       
   309 					prefix.cf_cie_id_addr);
       
   310 
       
   311 	    res = dwarf_find_existing_cie_ptr(cieptr_val,
       
   312 					      cur_cie_ptr,
       
   313 					      &cie_ptr_to_use,
       
   314 					      head_cie_ptr);
       
   315 	    if (res == DW_DLV_OK) {
       
   316 		cur_cie_ptr = cie_ptr_to_use;
       
   317 		/* Ok. Seen CIE already. */
       
   318 	    } else if (res == DW_DLV_NO_ENTRY) {
       
   319 		res = dwarf_create_cie_from_start(dbg,
       
   320 						  cieptr_val,
       
   321 						  section_ptr,
       
   322 						  section_index,
       
   323 						  section_length,
       
   324 						  frame_ptr_end,
       
   325 						  cie_id_value,
       
   326 						  cie_count,
       
   327 						  use_gnu_cie_calc,
       
   328 						  &cie_ptr_to_use,
       
   329 						  error);
       
   330 		if (res == DW_DLV_ERROR) {
       
   331 		    dealloc_fde_cie_list_internal(head_fde_ptr,
       
   332 						  head_cie_ptr);
       
   333 		    return res;
       
   334 		} else if (res == DW_DLV_NO_ENTRY) {
       
   335 		    return res;
       
   336 		}
       
   337 		++cie_count;
       
   338 		chain_up_cie(cie_ptr_to_use, &head_cie_ptr,
       
   339 			     &tail_cie_ptr);
       
   340                 cur_cie_ptr = tail_cie_ptr;
       
   341 
       
   342 	    } else {
       
   343 		/* DW_DLV_ERROR */
       
   344 		return res;
       
   345 	    }
       
   346 
       
   347 	    res = dwarf_create_fde_from_after_start(dbg,
       
   348 						    &prefix,
       
   349 						    section_ptr,
       
   350 						    frame_ptr,
       
   351 						    use_gnu_cie_calc,
       
   352 						    cie_ptr_to_use,
       
   353 						    &fde_ptr_to_use,
       
   354 						    error);
       
   355 	    if (res == DW_DLV_ERROR) {
       
   356 		return res;
       
   357 	    }
       
   358 	    chain_up_fde(fde_ptr_to_use, &head_fde_ptr, &cur_fde_ptr);
       
   359 	    fde_count++;
       
   360 	    /* ASSERT: DW_DLV_OK. */
       
   361 	    frame_ptr = fde_ptr_to_use->fd_fde_start +
       
   362 		fde_ptr_to_use->fd_length +
       
   363 		fde_ptr_to_use->fd_length_size +
       
   364 		fde_ptr_to_use->fd_extension_size;
       
   365 	    continue;
       
   366 
       
   367 	}
       
   368 
       
   369     }
       
   370 
       
   371     /* Now build list of CIEs from the list. */
       
   372     if (cie_count > 0) {
       
   373 	cie_list_ptr = (Dwarf_Cie *)
       
   374 	    _dwarf_get_alloc(dbg, DW_DLA_LIST, cie_count);
       
   375     } else {
       
   376 	dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr);
       
   377 	return (DW_DLV_NO_ENTRY);
       
   378     }
       
   379     if (cie_list_ptr == NULL) {
       
   380 	dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr);
       
   381 	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
       
   382 	return (DW_DLV_ERROR);
       
   383     }
       
   384     cur_cie_ptr = head_cie_ptr;
       
   385     for (i = 0; i < cie_count; i++) {
       
   386 	*(cie_list_ptr + i) = cur_cie_ptr;
       
   387 	cur_cie_ptr = cur_cie_ptr->ci_next;
       
   388     }
       
   389 
       
   390 
       
   391 
       
   392     /* Now build array of FDEs from the list. */
       
   393     if (fde_count > 0) {
       
   394 	fde_list_ptr = (Dwarf_Fde *)
       
   395 	    _dwarf_get_alloc(dbg, DW_DLA_LIST, fde_count);
       
   396     } else {
       
   397 	dwarf_fde_cie_list_dealloc(dbg, cie_list_ptr, cie_count,
       
   398 				   /* fde_data */ 0,
       
   399 				   /* fde_element_count */ 0);
       
   400 	dealloc_fde_cie_list_internal(head_fde_ptr,	/* head cie_ptr 
       
   401 							 */
       
   402 				      0);
       
   403 	return (DW_DLV_NO_ENTRY);
       
   404     }
       
   405     if (fde_list_ptr == NULL) {
       
   406 	dwarf_fde_cie_list_dealloc(dbg, cie_list_ptr, cie_count,
       
   407 				   /* fde_data */ 0,
       
   408 				   /* fde_element_count */ 0);
       
   409 	dealloc_fde_cie_list_internal(head_fde_ptr,	/* head cie_ptr 
       
   410 							 */
       
   411 				      0);
       
   412 	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
       
   413 	return (DW_DLV_ERROR);
       
   414     }
       
   415     cur_fde_ptr = head_fde_ptr;
       
   416     for (i = 0; i < fde_count; i++) {
       
   417 	*(fde_list_ptr + i) = cur_fde_ptr;
       
   418 	cur_fde_ptr = cur_fde_ptr->fd_next;
       
   419     }
       
   420 
       
   421 
       
   422     /* Return arguments. */
       
   423     *cie_data = cie_list_ptr;
       
   424     *cie_element_count = cie_count;
       
   425     dbg->de_cie_data = cie_list_ptr;
       
   426     dbg->de_cie_count = cie_count;
       
   427 
       
   428     *fde_data = fde_list_ptr;
       
   429     *fde_element_count = fde_count;
       
   430     dbg->de_fde_data = fde_list_ptr;
       
   431     dbg->de_fde_count = fde_count;
       
   432 
       
   433     /* Sort the list by the address so that dwarf_get_fde_at_pc() can
       
   434        binary search this list. */
       
   435     qsort((void *) fde_list_ptr, fde_count, sizeof(Dwarf_Ptr),
       
   436 	  qsort_compare);
       
   437 
       
   438     return (DW_DLV_OK);
       
   439 }
       
   440 
       
   441 /* Internal function, not called by consumer code.
       
   442    'prefix' has accumulated the info up thru the cie-id
       
   443    and now we consume the rest and build a Dwarf_Cie_s structure.
       
   444 */
       
   445 int
       
   446 dwarf_create_cie_from_after_start(Dwarf_Debug dbg,
       
   447 				  struct cie_fde_prefix_s *prefix,
       
   448 				  Dwarf_Small * section_pointer,
       
   449 				  Dwarf_Small * frame_ptr,
       
   450 				  Dwarf_Unsigned cie_count,
       
   451 				  int use_gnu_cie_calc,
       
   452 				  Dwarf_Cie * cie_ptr_out,
       
   453 				  Dwarf_Error * error)
       
   454 {
       
   455     Dwarf_Cie new_cie = 0;
       
   456 
       
   457     /* egcs-1.1.2 .eh_frame uses 0 as the distinguishing id. sgi uses
       
   458        -1 (in .debug_frame). .eh_frame not quite identical to
       
   459        .debug_frame */
       
   460     Dwarf_Small eh_fde_encoding = 0;
       
   461     Dwarf_Small *augmentation = 0;
       
   462     Dwarf_Sword data_alignment_factor = -1;
       
   463     Dwarf_Word code_alignment_factor = 4;
       
   464     Dwarf_Unsigned return_address_register = 31;
       
   465     int local_length_size = 0;
       
   466     Dwarf_Word leb128_length = 0;
       
   467     Dwarf_Unsigned cie_aug_data_len = 0;
       
   468     Dwarf_Small *cie_aug_data = 0;
       
   469     Dwarf_Addr gnu_personality_handler_addr = 0;
       
   470     unsigned char gnu_personality_handler_encoding = 0;
       
   471     unsigned char gnu_lsda_encoding = 0;
       
   472     unsigned char gnu_fde_begin_encoding = 0;
       
   473 
       
   474 
       
   475     enum Dwarf_augmentation_type augt = aug_unknown;
       
   476 
       
   477 
       
   478     /* this is a CIE, Common Information Entry: See the dwarf spec,
       
   479        section 6.4.1 */
       
   480     Dwarf_Small version = *(Dwarf_Small *) frame_ptr;
       
   481 
       
   482     frame_ptr++;
       
   483     if (version != DW_CIE_VERSION && version != DW_CIE_VERSION3) {
       
   484 	_dwarf_error(dbg, error, DW_DLE_FRAME_VERSION_BAD);
       
   485 	return (DW_DLV_ERROR);
       
   486     }
       
   487 
       
   488     augmentation = frame_ptr;
       
   489     frame_ptr = frame_ptr + strlen((char *) frame_ptr) + 1;
       
   490     augt = _dwarf_get_augmentation_type(dbg,
       
   491 					augmentation, use_gnu_cie_calc);
       
   492     if (augt == aug_eh) {
       
   493 	/* REFERENCED *//* Not used in this instance */
       
   494 	Dwarf_Unsigned exception_table_addr;
       
   495 
       
   496 	/* this is per egcs-1.1.2 as on RH 6.0 */
       
   497 	READ_UNALIGNED(dbg, exception_table_addr,
       
   498 		       Dwarf_Unsigned, frame_ptr, local_length_size);
       
   499 	frame_ptr += local_length_size;
       
   500     }
       
   501     {
       
   502 	Dwarf_Unsigned lreg = 0;
       
   503 	unsigned long size = 0;
       
   504 
       
   505 	DECODE_LEB128_UWORD(frame_ptr, lreg);
       
   506 	code_alignment_factor = (Dwarf_Word) lreg;
       
   507 
       
   508 	data_alignment_factor =
       
   509 	    (Dwarf_Sword) _dwarf_decode_s_leb128(frame_ptr,
       
   510 						 &leb128_length);
       
   511 
       
   512 	frame_ptr = frame_ptr + leb128_length;
       
   513 
       
   514 	return_address_register =
       
   515 	    _dwarf_get_return_address_reg(frame_ptr, version, &size);
       
   516 	if (return_address_register > DW_FRAME_LAST_REG_NUM) {
       
   517 	    _dwarf_error(dbg, error, DW_DLE_CIE_RET_ADDR_REG_ERROR);
       
   518 	    return (DW_DLV_ERROR);
       
   519 	}
       
   520 	frame_ptr += size;
       
   521     }
       
   522     switch (augt) {
       
   523     case aug_empty_string:
       
   524 	break;
       
   525     case aug_irix_mti_v1:
       
   526 	break;
       
   527     case aug_irix_exception_table:{
       
   528 	    Dwarf_Unsigned lreg = 0;
       
   529 	    Dwarf_Word length_of_augmented_fields;
       
   530 
       
   531 	    /* Decode the length of augmented fields. */
       
   532 	    DECODE_LEB128_UWORD(frame_ptr, lreg);
       
   533 	    length_of_augmented_fields = (Dwarf_Word) lreg;
       
   534 
       
   535 
       
   536 	    /* set the frame_ptr to point at the instruction start. */
       
   537 	    frame_ptr += length_of_augmented_fields;
       
   538 	}
       
   539 	break;
       
   540 
       
   541     case aug_eh:{
       
   542 
       
   543 	    int err = 0;
       
   544 	    unsigned long increment = 0;
       
   545 
       
   546 	    if (!use_gnu_cie_calc) {
       
   547 		/* This should be impossible. */
       
   548 		_dwarf_error(dbg, error,
       
   549 			     DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
       
   550 		return DW_DLV_ERROR;
       
   551 	    }
       
   552 
       
   553 	    err = get_gcc_eh_augmentation(dbg, frame_ptr, &increment,
       
   554 					  augt,
       
   555 					  prefix->cf_section_ptr,
       
   556 					  &eh_fde_encoding,
       
   557 					  (char *) augmentation);
       
   558 	    if (err == DW_DLV_ERROR) {
       
   559 		_dwarf_error(dbg, error,
       
   560 			     DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
       
   561 		return DW_DLV_ERROR;
       
   562 	    }
       
   563 	    frame_ptr += increment;
       
   564 	    break;
       
   565 	}
       
   566     case aug_gcc_eh_z:{
       
   567 	    /* Here we have Augmentation Data Length (uleb128) followed 
       
   568 	       by Augmentation Data bytes. */
       
   569 	    int res;
       
   570 	    Dwarf_Unsigned adlen = 0;
       
   571 
       
   572 	    DECODE_LEB128_UWORD(frame_ptr, adlen);
       
   573 	    cie_aug_data_len = adlen;
       
   574 	    cie_aug_data = frame_ptr;
       
   575 	    res = gnu_aug_encodings(dbg,
       
   576 				    (char *) augmentation,
       
   577 				    cie_aug_data,
       
   578 				    cie_aug_data_len,
       
   579 				    &gnu_personality_handler_encoding,
       
   580 				    &gnu_lsda_encoding,
       
   581 				    &gnu_fde_begin_encoding,
       
   582 				    &gnu_personality_handler_addr);
       
   583 	    if (res != DW_DLV_OK) {
       
   584 		_dwarf_error(dbg, error,
       
   585 			     DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
       
   586 		return res;
       
   587 	    }
       
   588 
       
   589 
       
   590 	    frame_ptr += adlen;
       
   591 	    break;
       
   592 	}
       
   593     default:{
       
   594 	    /* We do not understand the augmentation string. No
       
   595 	       assumption can be made about any fields other than what
       
   596 	       we have already read. */
       
   597 	    frame_ptr = prefix->cf_start_addr +
       
   598 		prefix->cf_length + prefix->cf_local_length_size
       
   599 		+ prefix->cf_local_extension_size;
       
   600 	    /* FIX -- What are the values of data_alignment_factor,
       
   601 	       code_alignement_factor, return_address_register and
       
   602 	       instruction start? They were clearly uninitalized in the 
       
   603 	       previous version and I am leaving them the same way. */
       
   604 	    break;
       
   605 	}
       
   606     }				/* End switch on augmentation type. */
       
   607 
       
   608     new_cie = (Dwarf_Cie) _dwarf_get_alloc(dbg, DW_DLA_CIE, 1);
       
   609     if (new_cie == NULL) {
       
   610 	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
       
   611 	return (DW_DLV_ERROR);
       
   612     }
       
   613 
       
   614     new_cie->ci_cie_version_number = version;
       
   615     new_cie->ci_initial_table = NULL;
       
   616     new_cie->ci_length = (Dwarf_Word) prefix->cf_length;
       
   617     new_cie->ci_length_size = prefix->cf_local_length_size;
       
   618     new_cie->ci_extension_size = prefix->cf_local_extension_size;
       
   619     new_cie->ci_augmentation = (char *) augmentation;
       
   620 
       
   621     new_cie->ci_data_alignment_factor =
       
   622 	(Dwarf_Sbyte) data_alignment_factor;
       
   623     new_cie->ci_code_alignment_factor =
       
   624 	(Dwarf_Small) code_alignment_factor;
       
   625     new_cie->ci_return_address_register = return_address_register;
       
   626     new_cie->ci_cie_start = prefix->cf_start_addr;
       
   627     new_cie->ci_cie_instr_start = frame_ptr;
       
   628     new_cie->ci_dbg = dbg;
       
   629     new_cie->ci_augmentation_type = augt;
       
   630     new_cie->ci_gnu_eh_augmentation_len = cie_aug_data_len;
       
   631     new_cie->ci_gnu_eh_augmentation_bytes = cie_aug_data;
       
   632     new_cie->ci_gnu_personality_handler_encoding =
       
   633 	gnu_personality_handler_encoding;
       
   634     new_cie->ci_gnu_personality_handler_addr =
       
   635 	gnu_personality_handler_addr;
       
   636     new_cie->ci_gnu_lsda_encoding = gnu_lsda_encoding;
       
   637     new_cie->ci_gnu_fde_begin_encoding = gnu_fde_begin_encoding;
       
   638 
       
   639     new_cie->ci_index = cie_count;
       
   640     new_cie->ci_section_ptr = prefix->cf_section_ptr;
       
   641 
       
   642     *cie_ptr_out = new_cie;
       
   643     return DW_DLV_OK;
       
   644 
       
   645 }
       
   646 
       
   647 
       
   648 /* Internal function, not called by consumer code.
       
   649    'prefix' has accumulated the info up thru the cie-id
       
   650    and now we consume the rest and build a Dwarf_Fde_s structure.
       
   651 */
       
   652 
       
   653 int
       
   654 dwarf_create_fde_from_after_start(Dwarf_Debug dbg,
       
   655 				  struct cie_fde_prefix_s *prefix,
       
   656 				  Dwarf_Small * section_pointer,
       
   657 				  Dwarf_Small * frame_ptr,
       
   658 				  int use_gnu_cie_calc,
       
   659 				  Dwarf_Cie cie_ptr_in,
       
   660 				  Dwarf_Fde * fde_ptr_out,
       
   661 				  Dwarf_Error * error)
       
   662 {
       
   663     Dwarf_Fde new_fde = 0;
       
   664     Dwarf_Cie cieptr = cie_ptr_in;
       
   665     Dwarf_Small *saved_frame_ptr = 0;
       
   666 
       
   667     Dwarf_Small *initloc = frame_ptr;
       
   668     Dwarf_Signed offset_into_exception_tables
       
   669 	/* must be min dwarf_sfixed in size */
       
   670 	= (Dwarf_Signed) DW_DLX_NO_EH_OFFSET;
       
   671     Dwarf_Small *fde_aug_data = 0;
       
   672     Dwarf_Unsigned fde_aug_data_len = 0;
       
   673     Dwarf_Addr cie_base_offset = prefix->cf_cie_id;
       
   674     Dwarf_Addr initial_location = 0;	/* must be min de_pointer_size
       
   675 					   bytes in size */
       
   676     Dwarf_Addr address_range = 0;	/* must be min de_pointer_size
       
   677 					   bytes in size */
       
   678 
       
   679     enum Dwarf_augmentation_type augt = cieptr->ci_augmentation_type;
       
   680 
       
   681     if (augt == aug_gcc_eh_z) {
       
   682 	/* If z augmentation this is eh_frame, and initial_location and 
       
   683 	   address_range in the FDE are read according to the CIE
       
   684 	   augmentation string instructions.  */
       
   685 
       
   686 	{
       
   687 	    Dwarf_Small *fp_updated = 0;
       
   688 	    int res = res = read_encoded_ptr(dbg,
       
   689 					     section_pointer,
       
   690 					     frame_ptr,
       
   691 					     cieptr->
       
   692 					     ci_gnu_fde_begin_encoding,
       
   693 					     &initial_location,
       
   694 					     &fp_updated);
       
   695 
       
   696 	    if (res != DW_DLV_OK) {
       
   697 		_dwarf_error(dbg, error,
       
   698 			     DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
       
   699 		return DW_DLV_ERROR;
       
   700 	    }
       
   701 	    frame_ptr = fp_updated;
       
   702 	    /* For the address-range it makes no sense to be
       
   703 	       pc-relative, so we turn it off with a section_pointer of 
       
   704 	       NULL. Masking off DW_EH_PE_pcrel from the
       
   705 	       ci_gnu_fde_begin_encoding in this call would also work
       
   706 	       to turn off DW_EH_PE_pcrel. */
       
   707 	    res = read_encoded_ptr(dbg, (Dwarf_Small *) NULL,
       
   708 				   frame_ptr,
       
   709 				   cieptr->ci_gnu_fde_begin_encoding,
       
   710 				   &address_range, &fp_updated);
       
   711 	    if (res != DW_DLV_OK) {
       
   712 		_dwarf_error(dbg, error,
       
   713 			     DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
       
   714 		return DW_DLV_ERROR;
       
   715 	    }
       
   716 	    frame_ptr = fp_updated;
       
   717 	}
       
   718 	{
       
   719 	    Dwarf_Unsigned adlen = 0;
       
   720 
       
   721 	    DECODE_LEB128_UWORD(frame_ptr, adlen);
       
   722 	    fde_aug_data_len = adlen;
       
   723 	    fde_aug_data = frame_ptr;
       
   724 	    frame_ptr += adlen;
       
   725 	}
       
   726 
       
   727     } else {
       
   728 	READ_UNALIGNED(dbg, initial_location, Dwarf_Addr,
       
   729 		       frame_ptr, dbg->de_pointer_size);
       
   730 	frame_ptr += dbg->de_pointer_size;
       
   731 
       
   732 	READ_UNALIGNED(dbg, address_range, Dwarf_Addr,
       
   733 		       frame_ptr, dbg->de_pointer_size);
       
   734 	frame_ptr += dbg->de_pointer_size;
       
   735     }
       
   736 
       
   737 
       
   738 
       
   739 
       
   740 
       
   741     switch (augt) {
       
   742     case aug_irix_mti_v1:
       
   743     case aug_empty_string:
       
   744 	break;
       
   745     case aug_irix_exception_table:{
       
   746 	    Dwarf_Unsigned lreg = 0;
       
   747 	    Dwarf_Word length_of_augmented_fields = 0;
       
   748 
       
   749 	    DECODE_LEB128_UWORD(frame_ptr, lreg);
       
   750 	    length_of_augmented_fields = (Dwarf_Word) lreg;
       
   751 
       
   752 	    saved_frame_ptr = frame_ptr;
       
   753 	    /* The first word is an offset into exception tables.
       
   754 	       Defined as a 32bit offset even for CC -64. */
       
   755 	    READ_UNALIGNED(dbg, offset_into_exception_tables,
       
   756 			   Dwarf_Addr, frame_ptr, sizeof(Dwarf_sfixed));
       
   757 	    SIGN_EXTEND(offset_into_exception_tables,
       
   758 			sizeof(Dwarf_sfixed));
       
   759 	    frame_ptr = saved_frame_ptr + length_of_augmented_fields;
       
   760 	}
       
   761 	break;
       
   762     case aug_eh:{
       
   763 	    Dwarf_Unsigned eh_table_value = 0;
       
   764 
       
   765 	    if (!use_gnu_cie_calc) {
       
   766 		/* This should be impossible. */
       
   767 		_dwarf_error(dbg, error,
       
   768 			     DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
       
   769 		return DW_DLV_ERROR;
       
   770 	    }
       
   771 
       
   772 	    /* gnu eh fde case. we do not need to do anything */
       
   773 	     /*REFERENCED*/	/* Not used in this instance of the
       
   774 				   macro */
       
   775 		READ_UNALIGNED(dbg, eh_table_value,
       
   776 			       Dwarf_Unsigned, frame_ptr,
       
   777 			       dbg->de_pointer_size);
       
   778 	    frame_ptr += dbg->de_pointer_size;
       
   779 	}
       
   780 	break;
       
   781 
       
   782     case aug_gcc_eh_z:{
       
   783 	    /* The Augmentation Data Length is here, followed by the
       
   784 	       Augmentation Data bytes themselves. */
       
   785 	}
       
   786 	break;
       
   787     case aug_past_last:
       
   788 	break;
       
   789     case aug_unknown:
       
   790 	_dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
       
   791 	return DW_DLV_ERROR;
       
   792     }				/* End switch on augmentation type */
       
   793     new_fde = (Dwarf_Fde) _dwarf_get_alloc(dbg, DW_DLA_FDE, 1);
       
   794     if (new_fde == NULL) {
       
   795 	_dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
       
   796 	return (DW_DLV_ERROR);
       
   797     }
       
   798 
       
   799     new_fde->fd_length = prefix->cf_length;
       
   800     new_fde->fd_length_size = prefix->cf_local_length_size;
       
   801     new_fde->fd_extension_size = prefix->cf_local_extension_size;
       
   802     new_fde->fd_cie_offset = cie_base_offset;
       
   803     new_fde->fd_cie_index = cieptr->ci_index;
       
   804     new_fde->fd_cie = cieptr;
       
   805     new_fde->fd_initial_location = initial_location;
       
   806     new_fde->fd_initial_loc_pos = initloc;
       
   807     new_fde->fd_address_range = address_range;
       
   808     new_fde->fd_fde_start = prefix->cf_start_addr;
       
   809     new_fde->fd_fde_instr_start = frame_ptr;
       
   810     new_fde->fd_dbg = dbg;
       
   811     new_fde->fd_offset_into_exception_tables =
       
   812 	offset_into_exception_tables;
       
   813 
       
   814     new_fde->fd_section_ptr = prefix->cf_section_ptr;
       
   815     new_fde->fd_section_index = prefix->cf_section_index;
       
   816     new_fde->fd_section_length = prefix->cf_section_length;
       
   817 
       
   818     new_fde->fd_gnu_eh_augmentation_bytes = fde_aug_data;
       
   819     new_fde->fd_gnu_eh_augmentation_len = fde_aug_data_len;
       
   820 
       
   821     *fde_ptr_out = new_fde;
       
   822     return DW_DLV_OK;
       
   823 }
       
   824 
       
   825 /* called by qsort to compare FDE entries.
       
   826    Consumer code expects the array of FDE pointers to be in address order.
       
   827 */
       
   828 static int
       
   829 qsort_compare(const void *elem1, const void *elem2)
       
   830 {
       
   831     Dwarf_Fde fde1 = *(Dwarf_Fde *) elem1;
       
   832     Dwarf_Fde fde2 = *(Dwarf_Fde *) elem2;
       
   833     Dwarf_Addr addr1 = fde1->fd_initial_location;
       
   834     Dwarf_Addr addr2 = fde2->fd_initial_location;
       
   835 
       
   836     if (addr1 < addr2) {
       
   837 	return -1;
       
   838     } else if (addr1 > addr2) {
       
   839 	return 1;
       
   840     }
       
   841     return 0;
       
   842 }
       
   843 
       
   844 
       
   845 /* Read in the common cie/fde prefix, including reading
       
   846  * the cie-value which shows which this is: cie or fde.
       
   847  * */
       
   848 int
       
   849 dwarf_read_cie_fde_prefix(Dwarf_Debug dbg,
       
   850 			  Dwarf_Small * frame_ptr_in,
       
   851 			  Dwarf_Small * section_ptr_in,
       
   852 			  Dwarf_Unsigned section_index_in,
       
   853 			  Dwarf_Unsigned section_length_in,
       
   854 			  struct cie_fde_prefix_s *data_out,
       
   855 			  Dwarf_Error * error)
       
   856 {
       
   857     Dwarf_Unsigned length = 0;
       
   858     int local_length_size = 0;
       
   859     int local_extension_size = 0;
       
   860     Dwarf_Small *frame_ptr = frame_ptr_in;
       
   861     Dwarf_Small *cie_ptr_addr = 0;
       
   862     Dwarf_Unsigned cie_id = 0;
       
   863 
       
   864     /* READ_AREA_LENGTH updates frame_ptr for consumed bytes */
       
   865     READ_AREA_LENGTH(dbg, length, Dwarf_Unsigned,
       
   866 		     frame_ptr, local_length_size,
       
   867 		     local_extension_size);
       
   868 
       
   869     if (length % local_length_size != 0) {
       
   870 	_dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);
       
   871 	return (DW_DLV_ERROR);
       
   872     }
       
   873 
       
   874     if (length == 0) {
       
   875 	/* nul bytes at end of section, seen at end of egcs eh_frame
       
   876 	   sections (in a.out). Take this as meaning no more CIE/FDE
       
   877 	   data. We should be very close to end of section. */
       
   878 	return DW_DLV_NO_ENTRY;
       
   879     }
       
   880 
       
   881     cie_ptr_addr = frame_ptr;
       
   882     READ_UNALIGNED(dbg, cie_id, Dwarf_Unsigned,
       
   883 		   frame_ptr, local_length_size);
       
   884     SIGN_EXTEND(cie_id, local_length_size);
       
   885     frame_ptr += local_length_size;
       
   886 
       
   887     data_out->cf_start_addr = frame_ptr_in;
       
   888     data_out->cf_addr_after_prefix = frame_ptr;
       
   889 
       
   890     data_out->cf_length = length;
       
   891     data_out->cf_local_length_size = local_length_size;
       
   892     data_out->cf_local_extension_size = local_extension_size;
       
   893     data_out->cf_cie_id = cie_id;
       
   894     data_out->cf_cie_id_addr = cie_ptr_addr;
       
   895     data_out->cf_section_ptr = section_ptr_in;
       
   896     data_out->cf_section_index = section_index_in;
       
   897     data_out->cf_section_length = section_length_in;
       
   898     return DW_DLV_OK;
       
   899 }
       
   900 
       
   901 /* On various errors previously-allocated CIEs and FDEs
       
   902    must be cleaned up.
       
   903    This helps avoid leaks in case of errors.
       
   904 */
       
   905 static void
       
   906 dealloc_fde_cie_list_internal(Dwarf_Fde head_fde_ptr,
       
   907 			      Dwarf_Cie head_cie_ptr)
       
   908 {
       
   909     Dwarf_Fde curfde = 0;
       
   910     Dwarf_Cie curcie = 0;
       
   911     Dwarf_Fde nextfde = 0;
       
   912     Dwarf_Cie nextcie = 0;
       
   913 
       
   914     for (curfde = head_fde_ptr; curfde; curfde = nextfde) {
       
   915 	nextfde = curfde->fd_next;
       
   916 	dwarf_dealloc(curfde->fd_dbg, curfde, DW_DLA_FDE);
       
   917     }
       
   918     for (curcie = head_cie_ptr; curcie; curcie = nextcie) {
       
   919 	Dwarf_Frame frame = curcie->ci_initial_table;
       
   920 
       
   921 	nextcie = curcie->ci_next;
       
   922 	if (frame)
       
   923 	    dwarf_dealloc(curcie->ci_dbg, frame, DW_DLA_FRAME);
       
   924 	dwarf_dealloc(curcie->ci_dbg, curcie, DW_DLA_CIE);
       
   925     }
       
   926 }
       
   927 
       
   928 /* Find the cie whose id value is given: the id
       
   929  * value is, per DWARF2/3, an offset in the section. 
       
   930  * For .debug_frame, zero is a legal offset. For
       
   931  * GNU .eh_frame it is not a legal offset.
       
   932  * 'cie_ptr' is a pointer into our section, not an offset. */
       
   933 static int
       
   934 dwarf_find_existing_cie_ptr(Dwarf_Small * cie_ptr,
       
   935 			    Dwarf_Cie cur_cie_ptr,
       
   936 			    Dwarf_Cie * cie_ptr_to_use_out,
       
   937 			    Dwarf_Cie head_cie_ptr)
       
   938 {
       
   939     Dwarf_Cie next = 0;
       
   940 
       
   941     if (cur_cie_ptr && cie_ptr == cur_cie_ptr->ci_cie_start) {
       
   942 	/* Usually, we use the same cie again and again. */
       
   943 	*cie_ptr_to_use_out = cur_cie_ptr;
       
   944 	return DW_DLV_OK;
       
   945     }
       
   946     for (next = head_cie_ptr; next; next = next->ci_next) {
       
   947 	if (cie_ptr == next->ci_cie_start) {
       
   948 	    *cie_ptr_to_use_out = next;
       
   949 	    return DW_DLV_OK;
       
   950 	}
       
   951     }
       
   952     return DW_DLV_NO_ENTRY;
       
   953 }
       
   954 
       
   955 
       
   956 /* We have a valid cie_ptr_val that has not been
       
   957  * turned into an internal Cie yet. Do so now.
       
   958  * Returns DW_DLV_OK or DW_DLV_ERROR, never
       
   959  * DW_DLV_NO_ENTRY.
       
   960 
       
   961  'section_ptr'    - Points to first byte of section data.
       
   962  'section_length' - Length of the section, in bytes.
       
   963  'frame_ptr_end'  - Points 1-past last byte of section data.
       
   964  * */
       
   965 static int
       
   966 dwarf_create_cie_from_start(Dwarf_Debug dbg,
       
   967 			    Dwarf_Small * cie_ptr_val,
       
   968 			    Dwarf_Small * section_ptr,
       
   969 			    Dwarf_Unsigned section_index,
       
   970 			    Dwarf_Unsigned section_length,
       
   971 			    Dwarf_Small * frame_ptr_end,
       
   972 			    Dwarf_Unsigned cie_id_value,
       
   973 			    Dwarf_Unsigned cie_count,
       
   974 			    int use_gnu_cie_calc,
       
   975 			    Dwarf_Cie * cie_ptr_to_use_out,
       
   976 			    Dwarf_Error * error)
       
   977 {
       
   978     struct cie_fde_prefix_s prefix;
       
   979     int res = 0;
       
   980     Dwarf_Small *frame_ptr = cie_ptr_val;
       
   981 
       
   982     if (frame_ptr < section_ptr || frame_ptr > frame_ptr_end) {
       
   983 	_dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);
       
   984 	return DW_DLV_ERROR;
       
   985     }
       
   986     /* First read in the 'common prefix' to figure out what * we are to 
       
   987        do with this entry. IF it's not a cie * we are in big trouble. */
       
   988     memset(&prefix, 0, sizeof(prefix));
       
   989     res = dwarf_read_cie_fde_prefix(dbg, frame_ptr, section_ptr,
       
   990 				    section_index, section_length,
       
   991 				    &prefix, error);
       
   992     if (res == DW_DLV_ERROR) {
       
   993 	return res;
       
   994     }
       
   995     if (res == DW_DLV_NO_ENTRY) {
       
   996 	/* error. */
       
   997 	_dwarf_error(dbg, error, DW_DLE_FRAME_CIE_DECODE_ERROR);
       
   998 	return DW_DLV_ERROR;
       
   999 
       
  1000     }
       
  1001 
       
  1002     if (prefix.cf_cie_id != cie_id_value) {
       
  1003 	_dwarf_error(dbg, error, DW_DLE_FRAME_CIE_DECODE_ERROR);
       
  1004 	return DW_DLV_ERROR;
       
  1005     }
       
  1006     frame_ptr = prefix.cf_addr_after_prefix;
       
  1007     res = dwarf_create_cie_from_after_start(dbg,
       
  1008 					    &prefix,
       
  1009 					    section_ptr,
       
  1010 					    frame_ptr,
       
  1011 					    cie_count,
       
  1012 					    use_gnu_cie_calc,
       
  1013 					    cie_ptr_to_use_out, error);
       
  1014 
       
  1015     return res;
       
  1016 
       
  1017 }
       
  1018 
       
  1019 
       
  1020 /* This is for gnu eh frames, the 'z' case.
       
  1021    We find the letter involved
       
  1022    Return the augmentation character and, if applicable,
       
  1023    the personality routine address.
       
  1024 
       
  1025    personality_routine_out - 
       
  1026 	if 'P' is augchar, is personality handler addr. 
       
  1027         Otherwise is not set.
       
  1028    aug_data  - if 'P' points  to data space of the
       
  1029    aug_data_len - length of areas aug_data points to.
       
  1030    
       
  1031 */
       
  1032 #if 0
       
  1033 /* For debugging only. */
       
  1034 void
       
  1035 dump_bytes(Dwarf_Small * start, long len)
       
  1036 {
       
  1037     Dwarf_Small *end = start + len;
       
  1038     Dwarf_Small *cur = start;
       
  1039 
       
  1040     for (; cur < end; cur++) {
       
  1041 	printf(" byte %d, data %02x\n", (int) (cur - start), *cur);
       
  1042     }
       
  1043 
       
  1044 }
       
  1045 #endif
       
  1046 static int
       
  1047 gnu_aug_encodings(Dwarf_Debug dbg, char *augmentation,
       
  1048 		  Dwarf_Small * aug_data, Dwarf_Unsigned aug_data_len,
       
  1049 		  unsigned char *pers_hand_enc_out,
       
  1050 		  unsigned char *lsda_enc_out,
       
  1051 		  unsigned char *fde_begin_enc_out,
       
  1052 		  Dwarf_Addr * gnu_pers_addr_out)
       
  1053 {
       
  1054     char *nc = 0;
       
  1055     Dwarf_Small *cur_aug_p = aug_data;
       
  1056     Dwarf_Small *end_aug_p = aug_data + aug_data_len;
       
  1057 
       
  1058     for (nc = augmentation; *nc; ++nc) {
       
  1059 	char c = *nc;
       
  1060 
       
  1061 	switch (c) {
       
  1062 	case 'z':
       
  1063             /* Means that the augmentation data is present. */
       
  1064 	    continue;
       
  1065 
       
  1066 	case 'S':
       
  1067             /* Indicates this is a signal stack frame.  Debuggers have to do 
       
  1068                special handling.  We don't need to do more than print this flag at 
       
  1069                the right time, though (see dwarfdump where it prints the augmentation
       
  1070                string). 
       
  1071                A signal stack frame (in some OS's) can only be
       
  1072                unwound (backtraced) by knowing it is a signal stack frame 
       
  1073                (perhaps by noticing the name of the function for the stack frame
       
  1074                if the name can be found somehow) and figuring
       
  1075                out (or knowing) how the kernel and libc pushed a structure
       
  1076                onto the stack and loading registers from that structure.
       
  1077                Totally different from normal stack unwinding.
       
  1078                This flag gives an unwinder a big leg up by decoupling the
       
  1079                'hint: this is a stack frame' from knowledge like
       
  1080                the function name (the name might be unavailable at unwind time).
       
  1081             */
       
  1082             break;
       
  1083             
       
  1084 	case 'L':
       
  1085 	    if (cur_aug_p > end_aug_p) {
       
  1086 		return DW_DLV_ERROR;
       
  1087 	    }
       
  1088 	    *lsda_enc_out = *(unsigned char *) cur_aug_p;
       
  1089 	    ++cur_aug_p;
       
  1090 	    break;
       
  1091 	case 'R':
       
  1092             /* Followed by a one byte argument giving the
       
  1093                pointer encoding for the address pointers in the fde. */
       
  1094 	    if (cur_aug_p >= end_aug_p) {
       
  1095 		return DW_DLV_ERROR;
       
  1096 	    }
       
  1097 	    *fde_begin_enc_out = *(unsigned char *) cur_aug_p;
       
  1098 	    ++cur_aug_p;
       
  1099 	    break;
       
  1100 	case 'P':{
       
  1101 		int res = 0;
       
  1102 		Dwarf_Small *updated_aug_p = 0;
       
  1103 		unsigned char encoding = 0;
       
  1104 
       
  1105 		if (cur_aug_p >= end_aug_p) {
       
  1106 		    return DW_DLV_ERROR;
       
  1107 		}
       
  1108 		encoding = *(unsigned char *) cur_aug_p;
       
  1109 		*pers_hand_enc_out = encoding;
       
  1110 		++cur_aug_p;
       
  1111 		if (cur_aug_p > end_aug_p) {
       
  1112 		    return DW_DLV_ERROR;
       
  1113 		}
       
  1114 		/* DW_EH_PE_pcrel makes no sense here, so we turn it
       
  1115 		   off via a section pointer of NULL. */
       
  1116 		res = read_encoded_ptr(dbg,
       
  1117 				       (Dwarf_Small *) NULL,
       
  1118 				       cur_aug_p,
       
  1119 				       encoding,
       
  1120 				       gnu_pers_addr_out,
       
  1121 				       &updated_aug_p);
       
  1122 		if (res != DW_DLV_OK) {
       
  1123 		    return res;
       
  1124 		}
       
  1125 		cur_aug_p = updated_aug_p;
       
  1126 		if (cur_aug_p > end_aug_p) {
       
  1127 		    return DW_DLV_ERROR;
       
  1128 		}
       
  1129 	    }
       
  1130 	    break;
       
  1131 	default:
       
  1132 	    return DW_DLV_ERROR;
       
  1133 
       
  1134 	}
       
  1135     }
       
  1136 
       
  1137     return DW_DLV_OK;
       
  1138 }
       
  1139 
       
  1140 /* Given augmentation character (the encoding) giving the
       
  1141 address format, read the address from input_field
       
  1142 and return an incremented value 1 past the input bytes of the
       
  1143 address.
       
  1144 Push the address read back thru the *addr pointer.
       
  1145 See LSB (Linux Standar Base)  exception handling documents. 
       
  1146 */
       
  1147 static int
       
  1148 read_encoded_ptr(Dwarf_Debug dbg,
       
  1149 		 Dwarf_Small * section_pointer,
       
  1150 		 Dwarf_Small * input_field,
       
  1151 		 int gnu_encoding,
       
  1152 		 Dwarf_Unsigned * addr,
       
  1153 		 Dwarf_Small ** input_field_updated)
       
  1154 {
       
  1155     Dwarf_Word length = 0;
       
  1156     int value_type = gnu_encoding & 0xf;
       
  1157     Dwarf_Small *input_field_original = input_field;
       
  1158 
       
  1159     if (gnu_encoding == 0xff) {
       
  1160 	/* There is no data here. */
       
  1161 
       
  1162 	*addr = 0;
       
  1163 	*input_field_updated = input_field;
       
  1164 	/* Should we return DW_DLV_NO_ENTRY? */
       
  1165 	return DW_DLV_OK;
       
  1166     }
       
  1167     switch (value_type) {
       
  1168     case DW_EH_PE_absptr:{
       
  1169 	    /* value_type is zero. Treat as pointer size of the object. 
       
  1170 	     */
       
  1171 	    Dwarf_Unsigned ret_value = 0;
       
  1172 
       
  1173 	    READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
       
  1174 			   input_field, dbg->de_pointer_size);
       
  1175 	    *addr = ret_value;
       
  1176 	    *input_field_updated = input_field + dbg->de_pointer_size;
       
  1177 	}
       
  1178 	break;
       
  1179     case DW_EH_PE_uleb128:{
       
  1180 	    Dwarf_Unsigned val = _dwarf_decode_u_leb128(input_field,
       
  1181 							&length);
       
  1182 
       
  1183 	    *addr = val;
       
  1184 	    *input_field_updated = input_field + length;
       
  1185 	}
       
  1186 	break;
       
  1187     case DW_EH_PE_udata2:{
       
  1188 	    Dwarf_Unsigned ret_value = 0;
       
  1189 
       
  1190 	    READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
       
  1191 			   input_field, 2);
       
  1192 	    *addr = ret_value;
       
  1193 	    *input_field_updated = input_field + 2;
       
  1194 	}
       
  1195 	break;
       
  1196 
       
  1197     case DW_EH_PE_udata4:{
       
  1198 
       
  1199 	    Dwarf_Unsigned ret_value = 0;
       
  1200 
       
  1201 	    /* ASSERT: sizeof(Dwarf_ufixed) == 4 */
       
  1202 	    READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
       
  1203 			   input_field, sizeof(Dwarf_ufixed));
       
  1204 	    *addr = ret_value;
       
  1205 	    *input_field_updated = input_field + sizeof(Dwarf_ufixed);
       
  1206 	}
       
  1207 	break;
       
  1208 
       
  1209     case DW_EH_PE_udata8:{
       
  1210 	    Dwarf_Unsigned ret_value = 0;
       
  1211 
       
  1212 	    /* ASSERT: sizeof(Dwarf_Unsigned) == 8 */
       
  1213 	    READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned,
       
  1214 			   input_field, sizeof(Dwarf_Unsigned));
       
  1215 	    *addr = ret_value;
       
  1216 	    *input_field_updated = input_field + sizeof(Dwarf_Unsigned);
       
  1217 	}
       
  1218 	break;
       
  1219 
       
  1220     case DW_EH_PE_sleb128:{
       
  1221 	    Dwarf_Signed val = _dwarf_decode_s_leb128(input_field,
       
  1222 						      &length);
       
  1223 
       
  1224 	    *addr = (Dwarf_Unsigned) val;
       
  1225 	    *input_field_updated = input_field + length;
       
  1226 	}
       
  1227 	break;
       
  1228     case DW_EH_PE_sdata2:{
       
  1229 	    Dwarf_Unsigned val = 0;
       
  1230 
       
  1231 	    READ_UNALIGNED(dbg, val, Dwarf_Unsigned, input_field, 2);
       
  1232 	    SIGN_EXTEND(val, 2);
       
  1233 	    *addr = (Dwarf_Unsigned) val;
       
  1234 	    *input_field_updated = input_field + 2;
       
  1235 	}
       
  1236 	break;
       
  1237 
       
  1238     case DW_EH_PE_sdata4:{
       
  1239 	    Dwarf_Unsigned val = 0;
       
  1240 
       
  1241 	    /* ASSERT: sizeof(Dwarf_ufixed) == 4 */
       
  1242 	    READ_UNALIGNED(dbg, val,
       
  1243 			   Dwarf_Unsigned, input_field,
       
  1244 			   sizeof(Dwarf_ufixed));
       
  1245 	    SIGN_EXTEND(val, sizeof(Dwarf_ufixed));
       
  1246 	    *addr = (Dwarf_Unsigned) val;
       
  1247 	    *input_field_updated = input_field + sizeof(Dwarf_ufixed);
       
  1248 	}
       
  1249 	break;
       
  1250     case DW_EH_PE_sdata8:{
       
  1251 	    Dwarf_Unsigned val = 0;
       
  1252 
       
  1253 	    /* ASSERT: sizeof(Dwarf_Unsigned) == 8 */
       
  1254 	    READ_UNALIGNED(dbg, val,
       
  1255 			   Dwarf_Unsigned, input_field,
       
  1256 			   sizeof(Dwarf_Unsigned));
       
  1257 	    *addr = (Dwarf_Unsigned) val;
       
  1258 	    *input_field_updated = input_field + sizeof(Dwarf_Unsigned);
       
  1259 	}
       
  1260 	break;
       
  1261     default:
       
  1262 	return DW_DLV_ERROR;
       
  1263 
       
  1264     };
       
  1265     /* The ELF ABI for gnu does not document the meaning of
       
  1266        DW_EH_PE_pcrel, which is awkward.  It apparently means the value 
       
  1267        we got above is pc-relative (meaning section-relative), so we
       
  1268        adjust the value. Section_pointer may be null if it is known
       
  1269        DW_EH_PE_pcrel cannot apply, such as for .debug_frame or for an
       
  1270        address-range value. */
       
  1271     if (section_pointer && ((gnu_encoding & 0x70) == DW_EH_PE_pcrel)) {
       
  1272 	/* Address (*addr) above is pc relative with respect to a
       
  1273 	   section. Add to the offset the base address (from elf) of
       
  1274 	   section and the distance of the field we are reading from
       
  1275 	   the section-beginning to get the actual address. */
       
  1276 	/* ASSERT: input_field_original >= section_pointer */
       
  1277 	Dwarf_Unsigned distance =
       
  1278 	    input_field_original - section_pointer;
       
  1279 	*addr += dbg->de_debug_frame_eh_addr + distance;
       
  1280     }
       
  1281 
       
  1282     return DW_DLV_OK;
       
  1283 }
       
  1284 
       
  1285 
       
  1286 
       
  1287 
       
  1288 /* 
       
  1289 	All augmentation string checking done here now.
       
  1290 
       
  1291 	For .eh_frame, gcc from 3.3 uses the z style, earlier used
       
  1292  	only "eh" as augmentation.  We don't yet handle 
       
  1293         decoding .eh_frame with the z style extensions like L P. 
       
  1294 
       
  1295 	These are nasty heuristics, but then that's life
       
  1296         as augmentations are implementation specific.
       
  1297 */
       
  1298 /* ARGSUSED */
       
  1299 enum Dwarf_augmentation_type
       
  1300 _dwarf_get_augmentation_type(Dwarf_Debug dbg,
       
  1301 			     Dwarf_Small * augmentation_string,
       
  1302 			     int is_gcc_eh_frame)
       
  1303 {
       
  1304     enum Dwarf_augmentation_type t = aug_unknown;
       
  1305     char *ag_string = (char *) augmentation_string;
       
  1306 
       
  1307     if (ag_string[0] == 0) {
       
  1308 	/* Empty string. We'll just guess that we know what this means: 
       
  1309 	   standard dwarf2/3 with no implementation-defined fields.  */
       
  1310 	t = aug_empty_string;
       
  1311     } else if (strcmp(ag_string, DW_DEBUG_FRAME_AUGMENTER_STRING) == 0) {
       
  1312 	/* The string is "mti v1". Used internally at SGI, probably
       
  1313 	   never shipped. Replaced by "z". Treat like 'nothing
       
  1314 	   special'.  */
       
  1315 	t = aug_irix_mti_v1;
       
  1316     } else if (ag_string[0] == 'z') {
       
  1317 	/* If it's IRIX cc, z means aug_irix_exception_table. z1 z2
       
  1318 	   were designed as for IRIX CC, but never implemented */
       
  1319 	/* If it's gcc, z may be any of several things. "z" or z
       
  1320 	   followed optionally followed by one or more of L R P, each
       
  1321 	   of which means a value may be present. Should be in eh_frame 
       
  1322 	   only, I think. */
       
  1323 	if (is_gcc_eh_frame) {
       
  1324 	    t = aug_gcc_eh_z;
       
  1325 	} else if (ag_string[1] == 0) {
       
  1326 	    /* This is the normal IRIX C++ case, where there is an
       
  1327 	       offset into a table in each fde. The table being for
       
  1328 	       IRIX CC exception handling.  */
       
  1329 	    /* DW_CIE_AUGMENTER_STRING_V0 "z" */
       
  1330 	    t = aug_irix_exception_table;
       
  1331 	}			/* Else unknown. */
       
  1332     } else if (strncmp(ag_string, "eh", 2) == 0) {
       
  1333 	/* gcc .eh_frame augmentation for egcs and gcc 2.x, at least
       
  1334 	   for x86. */
       
  1335 	t = aug_eh;
       
  1336     }
       
  1337     return t;
       
  1338 }
       
  1339 
       
  1340 /* Using augmentation, and version 
       
  1341    read in the augmentation data for GNU eh. 
       
  1342 
       
  1343    Return DW_DLV_OK if we succeeded,
       
  1344    DW_DLV_ERR if we fail.
       
  1345 
       
  1346    On success, update  'size_of_augmentation_data' with
       
  1347    the length of the fields that are part of augmentation (so the
       
  1348    caller can increment frame_ptr appropriately).
       
  1349 
       
  1350    'frame_ptr' points within section.
       
  1351    'section_pointer' points to section base address in memory.
       
  1352 */
       
  1353 /* ARGSUSED */
       
  1354 static int
       
  1355 get_gcc_eh_augmentation(Dwarf_Debug dbg, Dwarf_Small * frame_ptr,
       
  1356 			unsigned long *size_of_augmentation_data,
       
  1357 			enum Dwarf_augmentation_type augtype,
       
  1358 			Dwarf_Small * section_pointer,
       
  1359 			Dwarf_Small * fde_eh_encoding_out,
       
  1360 			char *augmentation)
       
  1361 {
       
  1362     char *suffix = 0;
       
  1363     unsigned long augdata_size = 0;
       
  1364 
       
  1365     if (augtype == aug_gcc_eh_z) {
       
  1366 	/* Has leading 'z'. */
       
  1367 	Dwarf_Word leb128_length = 0;
       
  1368 
       
  1369 	/* Dwarf_Unsigned eh_value = */
       
  1370 	_dwarf_decode_u_leb128(frame_ptr, &leb128_length);
       
  1371 	augdata_size += leb128_length;
       
  1372 	frame_ptr += leb128_length;
       
  1373 	suffix = augmentation + 1;
       
  1374     } else {
       
  1375 	/* Prefix is 'eh'.  As in gcc 3.2. No suffix present
       
  1376 	   apparently. */
       
  1377 	suffix = augmentation + 2;
       
  1378     }
       
  1379     for (; *suffix; ++suffix) {
       
  1380 	/* We have no idea what this is as yet. Some extensions beyond
       
  1381 	   dwarf exist which we do not yet handle. */
       
  1382 	return DW_DLV_ERROR;
       
  1383 
       
  1384     }
       
  1385 
       
  1386     *size_of_augmentation_data = augdata_size;
       
  1387     return DW_DLV_OK;
       
  1388 }
       
  1389 
       
  1390 
       
  1391 /* Make the 'cie_id_addr' consistent across .debug_frame and .eh_frame.
       
  1392    Calculate a pointer into section bytes given a cie_id, which is
       
  1393    trivial for .debug_frame, but a bit more work for .eh_frame.  
       
  1394 */
       
  1395 static Dwarf_Small *
       
  1396 get_cieptr_given_offset(Dwarf_Unsigned cie_id_value,
       
  1397 			int use_gnu_cie_calc,
       
  1398 			Dwarf_Small * section_ptr,
       
  1399 			Dwarf_Small * cie_id_addr)
       
  1400 {
       
  1401     Dwarf_Small *cieptr = 0;
       
  1402 
       
  1403     if (use_gnu_cie_calc) {
       
  1404 	/* cie_id value is offset, in section, of the cie_id itself, to 
       
  1405 	   use vm ptr of the value, less the value, to get to the cie
       
  1406 	   itself. In addition, munge *cie_id_addr to look *as if* it
       
  1407 	   was from real dwarf. */
       
  1408 	cieptr = (Dwarf_Small *) ((Dwarf_Unsigned) cie_id_addr) -
       
  1409 	    ((Dwarf_Unsigned) cie_id_value);
       
  1410     } else {
       
  1411 	/* Traditional dwarf section offset is in cie_id */
       
  1412 	cieptr = (section_ptr + cie_id_value);
       
  1413     }
       
  1414     return cieptr;
       
  1415 }
       
  1416 
       
  1417 /* To properly release all spaced used.
       
  1418    Earlier approaches (before July 15, 2005)
       
  1419    letting client do the dealloc directly left
       
  1420    some data allocated.
       
  1421    This is directly called by consumer code.
       
  1422 */
       
  1423 void
       
  1424 dwarf_fde_cie_list_dealloc(Dwarf_Debug dbg,
       
  1425 			   Dwarf_Cie * cie_data,
       
  1426 			   Dwarf_Signed cie_element_count,
       
  1427 			   Dwarf_Fde * fde_data,
       
  1428 			   Dwarf_Signed fde_element_count)
       
  1429 {
       
  1430     Dwarf_Signed i = 0;
       
  1431 
       
  1432     for (i = 0; i < cie_element_count; ++i) {
       
  1433 	Dwarf_Frame frame = cie_data[i]->ci_initial_table;
       
  1434 
       
  1435 	if (frame)
       
  1436 	    dwarf_dealloc(dbg, frame, DW_DLA_FRAME);
       
  1437 	dwarf_dealloc(dbg, cie_data[i], DW_DLA_CIE);
       
  1438     }
       
  1439     for (i = 0; i < fde_element_count; ++i) {
       
  1440 	dwarf_dealloc(dbg, fde_data[i], DW_DLA_FDE);
       
  1441     }
       
  1442     if (cie_data)
       
  1443 	dwarf_dealloc(dbg, cie_data, DW_DLA_LIST);
       
  1444     if (fde_data)
       
  1445 	dwarf_dealloc(dbg, fde_data, DW_DLA_LIST);
       
  1446 
       
  1447 }