xref: /illumos-gate/usr/src/lib/libdwarf/common/dwarf_frame2.c (revision d48be21240dfd051b689384ce2b23479d757f2d8)
1 /*
2   Copyright (C) 2000-2006 Silicon Graphics, Inc.  All Rights Reserved.
3   Portions Copyright (C) 2007-2020 David Anderson. All Rights Reserved.
4   Portions Copyright (C) 2010-2012 SN Systems Ltd. All Rights Reserved.
5 
6   This program is free software; you can redistribute it
7   and/or modify it under the terms of version 2.1 of the
8   GNU Lesser General Public License as published by the Free
9   Software Foundation.
10 
11   This program is distributed in the hope that it would be
12   useful, but WITHOUT ANY WARRANTY; without even the implied
13   warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
14   PURPOSE.
15 
16   Further, this software is distributed without any warranty
17   that it is free of the rightful claim of any third person
18   regarding infringement or the like.  Any license provided
19   herein, whether implied or otherwise, applies only to this
20   software file.  Patent licenses, if any, provided herein
21   do not apply to combinations of this program with other
22   software, or any other product whatsoever.
23 
24   You should have received a copy of the GNU Lesser General
25   Public License along with this program; if not, write the
26   Free Software Foundation, Inc., 51 Franklin Street - Fifth
27   Floor, Boston MA 02110-1301, USA.
28 
29 */
30 
31 /*  This  implements _dwarf_get_fde_list_internal()
32     and related helper functions for reading cie/fde data.  */
33 
34 #include "config.h"
35 #include <stdio.h>
36 #ifdef HAVE_STDLIB_H
37 #include <stdlib.h>
38 #endif /* HAVE_STDLIB_H */
39 #include "dwarf_incl.h"
40 #include "dwarf_alloc.h"
41 #include "dwarf_error.h"
42 #include "dwarf_util.h"
43 #include "dwarf_frame.h"
44 #include "dwarf_arange.h" /* using Arange as a way to build a list */
45 #include "dwarfstring.h"
46 
47 /*  For a little information about .eh_frame see
48     https://stackoverflow.com/questions/14091231/what-do-the-eh-frame-and-eh-frame-hdr-sections-store-exactly
49     http://refspecs.linuxfoundation.org/LSB_3.0.0/LSB-Core-generic/LSB-Core-generic/ehframechpt.html
50     The above give information about fields and sizes but
51     very very little about content.
52 
53     .eh_frame_hdr contains data for C++ unwinding. Namely
54     tables for fast access into .eh_frame.
55 */
56 
57 
58 
59 #define TRUE 1
60 #define FALSE 0
61 
62 #if 0  /* FOR DEBUGGING */
63 /* For debugging only. */
64 static void
65 dump_bytes(const char *msg,Dwarf_Small * start, long len)
66 {
67     Dwarf_Small *end = start + len;
68     Dwarf_Small *cur = start;
69     printf("%s (0x%lx) ",msg,(unsigned long)start);
70     for (; cur < end; cur++) {
71         printf("%02x", *cur);
72     }
73     printf("\n");
74 }
75 
76 #endif
77 
78 static int dwarf_find_existing_cie_ptr(Dwarf_Small * cie_ptr,
79     Dwarf_Cie cur_cie_ptr,
80     Dwarf_Cie * cie_ptr_to_use_out,
81     Dwarf_Cie head_cie_ptr);
82 static void dealloc_fde_cie_list_internal(Dwarf_Fde head_fde_ptr,
83     Dwarf_Cie head_cie_ptr);
84 static int dwarf_create_cie_from_start(Dwarf_Debug dbg,
85     Dwarf_Small * cie_ptr_val,
86     Dwarf_Small * section_ptr,
87     Dwarf_Unsigned section_index,
88     Dwarf_Unsigned section_length,
89     Dwarf_Small * section_ptr_end,
90     Dwarf_Unsigned cie_id_value,
91     Dwarf_Unsigned cie_count,
92     int use_gnu_cie_calc,
93     Dwarf_Cie * cie_ptr_to_use_out,
94     Dwarf_Error * error);
95 
96 static int get_gcc_eh_augmentation(Dwarf_Debug dbg,
97     Dwarf_Small * frame_ptr,
98     unsigned long
99     *size_of_augmentation_data,
100     enum Dwarf_augmentation_type augtype,
101     Dwarf_Small * section_end_pointer,
102     char *augmentation,
103     Dwarf_Error *error);
104 
105 static int
106 gnu_aug_encodings(Dwarf_Debug dbg, char *augmentation,
107     Dwarf_Small * aug_data, Dwarf_Unsigned aug_data_len,
108     Dwarf_Half address_size,
109     unsigned char *pers_hand_enc_out,
110     unsigned char *lsda_enc_out,
111     unsigned char *fde_begin_enc_out,
112     Dwarf_Addr * gnu_pers_addr_out,
113     Dwarf_Error *error);
114 
115 
116 static int read_encoded_ptr(Dwarf_Debug dbg,
117     Dwarf_Small * section_pointer,
118     Dwarf_Small * input_field,
119     int gnu_encoding,
120     Dwarf_Small * section_ptr_end,
121     Dwarf_Half address_size,
122     Dwarf_Unsigned * addr,
123     Dwarf_Small ** input_field_out,
124     Dwarf_Error *error);
125 
126 
127 
128 /*  Called by qsort to compare FDE entries.
129     Consumer code expects the array of FDE pointers to be
130     in address order.
131 */
132 static int
133 qsort_compare(const void *elem1, const void *elem2)
134 {
135     const Dwarf_Fde fde1 = *(const Dwarf_Fde *) elem1;
136     const Dwarf_Fde fde2 = *(const Dwarf_Fde *) elem2;
137     Dwarf_Addr addr1 = fde1->fd_initial_location;
138     Dwarf_Addr addr2 = fde2->fd_initial_location;
139 
140     if (addr1 < addr2) {
141         return -1;
142     } else if (addr1 > addr2) {
143         return 1;
144     }
145     return 0;
146 }
147 
148 /*  Adds 'newone' to the end of the list starting at 'head'
149     and makes the new one 'cur'rent. */
150 static void
151 chain_up_fde(Dwarf_Fde newone, Dwarf_Fde * head, Dwarf_Fde * cur)
152 {
153     if (*head == NULL)
154         *head = newone;
155     else {
156         (*cur)->fd_next = newone;
157     }
158     *cur = newone;
159 
160 }
161 
162 /*  Adds 'newone' to the end of the list starting at 'head'
163     and makes the new one 'cur'rent. */
164 static void
165 chain_up_cie(Dwarf_Cie newone, Dwarf_Cie * head, Dwarf_Cie * cur)
166 {
167     if (*head == NULL) {
168         *head = newone;
169     } else {
170         (*cur)->ci_next = newone;
171     }
172     *cur = newone;
173 }
174 
175 /*  The size of the length field plus the
176     value of length must be an integral
177     multiple of the address size.  Dwarf4 standard.
178 
179     A constant that gives the number of bytes of the CIE
180     structure, not including the length field itself
181     (where length mod <size of an address> == 0)
182     (see Section 7.2.2). Dwarf3 standard.
183 
184     A uword constant that gives the number of bytes of
185     the CIE structure, not including the
186     length field, itself (length mod <addressing unit size> == 0).
187     Dwarf2 standard.*/
188 static void
189 validate_length(Dwarf_Debug dbg,
190     Dwarf_Cie cieptr, Dwarf_Unsigned length,
191     Dwarf_Unsigned length_size,
192     Dwarf_Unsigned extension_size,
193     Dwarf_Small * section_ptr,
194     Dwarf_Small * ciefde_start,
195     const char * cieorfde)
196 {
197     Dwarf_Unsigned address_size = 0;
198     Dwarf_Unsigned length_field_summed = length_size + extension_size;
199     Dwarf_Unsigned total_len = length + length_field_summed;
200     Dwarf_Unsigned mod = 0;
201 
202     if (cieptr) {
203         address_size = cieptr->ci_address_size;
204     } else {
205         address_size = dbg->de_pointer_size;
206     }
207     mod = total_len % address_size;
208     if (mod != 0) {
209         dwarfstring  harm;
210         Dwarf_Unsigned sectionoffset = ciefde_start - section_ptr;
211 
212         dwarfstring_constructor(&harm);
213         if (!cieorfde || (strlen(cieorfde) > 3)) {
214             /*  Coding error or memory corruption? */
215             cieorfde = "ERROR!";
216         }
217         dwarfstring_append_printf_u(&harm,
218             "DW_DLE_DEBUG_FRAME_LENGTH_NOT_MULTIPLE"
219             " len=0x%" DW_PR_XZEROS DW_PR_DUx,
220             length);
221         dwarfstring_append_printf_u(&harm,
222             ", len size=0x%"  DW_PR_XZEROS DW_PR_DUx,
223             length_size);
224         dwarfstring_append_printf_u(&harm,
225             ", extn size=0x%" DW_PR_XZEROS DW_PR_DUx,
226             extension_size);
227         dwarfstring_append_printf_u(&harm,
228             ", totl length=0x%" DW_PR_XZEROS DW_PR_DUx,
229             total_len);
230         dwarfstring_append_printf_u(&harm,
231             ", addr size=0x%" DW_PR_XZEROS DW_PR_DUx,
232             address_size);
233         dwarfstring_append_printf_u(&harm,
234             ", mod=0x%" DW_PR_XZEROS DW_PR_DUx " must be zero",
235             mod);
236         dwarfstring_append_printf_s(&harm,
237             " in %s",(char *)cieorfde);
238         dwarfstring_append_printf_u(&harm,
239             ", offset 0x%" DW_PR_XZEROS DW_PR_DUx ".",
240             sectionoffset);
241         dwarf_insert_harmless_error(dbg,
242             dwarfstring_string(&harm));
243         dwarfstring_destructor(&harm);
244     }
245     return;
246 }
247 
248 
249 #if 0 /* FOR DEBUGGING */
250 /* For debugging only. */
251 static void
252 print_prefix(struct cie_fde_prefix_s *prefix, int line)
253 {
254     printf("prefix-print, prefix at 0x%lx, line %d\n",
255         (unsigned long) prefix, line);
256     printf("  start addr 0x%lx after prefix 0x%lx\n",
257         (unsigned long) prefix->cf_start_addr,
258         (unsigned long) prefix->cf_addr_after_prefix);
259     printf("  length 0x%" DW_PR_DUx ", len size %d ext size %d\n",
260         (Dwarf_Unsigned) prefix->cf_length,
261         prefix->cf_local_length_size,
262         prefix->cf_local_extension_size);
263     printf("  cie_id 0x%" DW_PR_DUx " cie_id  cie_id_addr 0x%lx\n",
264         (Dwarf_Unsigned) prefix->cf_cie_id,
265         (long) prefix->cf_cie_id_addr);
266     printf
267         ("  sec ptr 0x%lx sec index %" DW_PR_DSd " sec len 0x%" DW_PR_DUx " sec past end 0x%lx\n",
268         (unsigned long) prefix->cf_section_ptr,
269         (Dwarf_Signed) prefix->cf_section_index,
270         (Dwarf_Unsigned) prefix->cf_section_length,
271         (unsigned long) prefix->cf_section_ptr +
272         (unsigned long)prefix->cf_section_length);
273 }
274 #endif
275 
276 /*  Make the 'cieptr' consistent across .debug_frame and .eh_frame.
277     Calculate a pointer into section bytes given a cie_id in
278     an FDE header.
279 
280     In .debug_frame, the CIE_pointer is an offset in .debug_frame.
281 
282     In .eh_frame, the CIE Pointer is, when
283     cie_id_value subtracted from the
284     cie_id_addr, the address in memory of
285     a CIE length field.
286     Since cie_id_addr is the address of an FDE CIE_Pointer
287     field, cie_id_value for .eh_frame
288     has to account for the length-prefix.
289     so that the returned cieptr really points to
290     a  CIE length field. Whew!
291     Available documentation on this is just a bit
292     ambiguous, but this calculation is correct.
293 */
294 
295 static Dwarf_Small *
296 get_cieptr_given_offset(Dwarf_Unsigned cie_id_value,
297     int use_gnu_cie_calc,
298     Dwarf_Small * section_ptr,
299     Dwarf_Small * cie_id_addr)
300 {
301     Dwarf_Small *cieptr = 0;
302 
303     if (use_gnu_cie_calc) {
304         /*  cie_id value is offset, in section, of the cie_id itself, to
305             use vm ptr of the value, less the value, to get to the cie
306             header.  */
307         cieptr = cie_id_addr - cie_id_value;
308     } else {
309         /*  Traditional dwarf section offset is in cie_id */
310         cieptr = section_ptr + cie_id_value;
311     }
312     return cieptr;
313 }
314 
315 
316 
317 /*  Internal function called from various places to create
318     lists of CIEs and FDEs.  Not directly called
319     by consumer code */
320 int
321 _dwarf_get_fde_list_internal(Dwarf_Debug dbg, Dwarf_Cie ** cie_data,
322     Dwarf_Signed * cie_element_count,
323     Dwarf_Fde ** fde_data,
324     Dwarf_Signed * fde_element_count,
325     Dwarf_Small * section_ptr,
326     Dwarf_Unsigned section_index,
327     Dwarf_Unsigned section_length,
328     Dwarf_Unsigned cie_id_value,
329     int use_gnu_cie_calc, Dwarf_Error * error)
330 {
331     /* Scans the debug_frame section. */
332     Dwarf_Small *frame_ptr = section_ptr;
333     Dwarf_Small *section_ptr_end = section_ptr + section_length;
334 
335 
336 
337     /*  New_cie points to the Cie being read, and head_cie_ptr and
338         cur_cie_ptr are used for chaining them up in sequence.
339         In case cie's are reused aggressively we need tail_cie_ptr
340         to add to the chain.  If we re-use an early cie
341         later on, that does not mean we chain a new cie to the early one,
342         we always chain it to the tail.  */
343     Dwarf_Cie head_cie_ptr = NULL;
344     Dwarf_Cie cur_cie_ptr = NULL;
345     Dwarf_Cie tail_cie_ptr = NULL;
346     Dwarf_Unsigned cie_count = 0;
347 
348     /*  Points to a list of contiguous pointers to Dwarf_Cie structures.
349     */
350     Dwarf_Cie *cie_list_ptr = 0;
351 
352 
353     /*  New_fde points to the Fde being created, and head_fde_ptr and
354         cur_fde_ptr are used to chain them up. */
355     Dwarf_Fde head_fde_ptr = NULL;
356     Dwarf_Fde cur_fde_ptr = NULL;
357     Dwarf_Unsigned fde_count = 0;
358 
359     /*  Points to a list of contiguous pointers to Dwarf_Fde structures.
360     */
361     Dwarf_Fde *fde_list_ptr = NULL;
362 
363     Dwarf_Unsigned i = 0;
364     int res = DW_DLV_ERROR;
365 
366     if (frame_ptr == 0) {
367         return DW_DLV_NO_ENTRY;
368     }
369 
370     /*  We create the fde and cie arrays. Processing each CIE as we come
371         to it or as an FDE refers to it.  We cannot process 'late' CIEs
372         late as GNU .eh_frame complexities mean we need the whole CIE
373         before we can process the FDE correctly. */
374     while (frame_ptr < section_ptr_end) {
375 
376         struct cie_fde_prefix_s prefix;
377 
378         /*  First read in the 'common prefix' to figure out what we are
379             to do with this entry. */
380         memset(&prefix, 0, sizeof(prefix));
381         res = dwarf_read_cie_fde_prefix(dbg,
382             frame_ptr, section_ptr,
383             section_index,
384             section_length, &prefix, error);
385         if (res == DW_DLV_ERROR) {
386             dealloc_fde_cie_list_internal(head_fde_ptr,
387                 head_cie_ptr);
388             return res;
389         }
390         if (res == DW_DLV_NO_ENTRY) {
391             break;
392         }
393         frame_ptr = prefix.cf_addr_after_prefix;
394         if (frame_ptr >= section_ptr_end) {
395             dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr);
396             _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);
397             return DW_DLV_ERROR;
398         }
399 
400         if (prefix.cf_cie_id == cie_id_value) {
401             /* This is a CIE.  */
402             Dwarf_Cie cie_ptr_to_use = 0;
403             int resc = 0;
404 
405             resc = dwarf_find_existing_cie_ptr(prefix.cf_start_addr,
406                 cur_cie_ptr,
407                 &cie_ptr_to_use,
408                 head_cie_ptr);
409             if (resc == DW_DLV_OK) {
410                 cur_cie_ptr = cie_ptr_to_use;
411                 /* Ok. Seen already. */
412             } else if (resc == DW_DLV_NO_ENTRY) {
413                 /* CIE before its FDE in this case. */
414                 resc = dwarf_create_cie_from_after_start(dbg,
415                     &prefix,
416                     section_ptr,
417                     frame_ptr,
418                     section_ptr_end,
419                     cie_count,
420                     use_gnu_cie_calc,
421                     &cie_ptr_to_use,
422                     error);
423                 if (resc != DW_DLV_OK) {
424                     dealloc_fde_cie_list_internal(head_fde_ptr,
425                         head_cie_ptr);
426                     return resc;
427                 }
428                 cie_count++;
429                 chain_up_cie(cie_ptr_to_use, &head_cie_ptr,
430                     &tail_cie_ptr);
431                 cur_cie_ptr = tail_cie_ptr;
432             } else {            /* res == DW_DLV_ERROR */
433 
434                 dealloc_fde_cie_list_internal(head_fde_ptr,
435                     head_cie_ptr);
436                 return resc;
437             }
438             frame_ptr = cie_ptr_to_use->ci_cie_start +
439                 cie_ptr_to_use->ci_length +
440                 cie_ptr_to_use->ci_length_size +
441                 cie_ptr_to_use->ci_extension_size;
442             continue;
443         } else {
444             /*  This is an FDE, Frame Description Entry, see the Dwarf
445                 Spec, (section 6.4.1 in DWARF2, DWARF3, DWARF4, ...)
446                 Or see the .eh_frame specification,
447                 from the Linux Foundation (or other source).  */
448             int resf = DW_DLV_ERROR;
449             Dwarf_Cie cie_ptr_to_use = 0;
450             Dwarf_Fde fde_ptr_to_use = 0;
451             Dwarf_Small *cieptr_val = 0;
452 
453             cieptr_val = get_cieptr_given_offset(prefix.cf_cie_id,
454                 use_gnu_cie_calc,
455                 section_ptr,
456                 prefix.cf_cie_id_addr);
457             resf = dwarf_find_existing_cie_ptr(cieptr_val,
458                 cur_cie_ptr,
459                 &cie_ptr_to_use,
460                 head_cie_ptr);
461             if (resf == DW_DLV_OK) {
462                 cur_cie_ptr = cie_ptr_to_use;
463                 /* Ok. Seen CIE already. */
464             } else if (resf == DW_DLV_NO_ENTRY) {
465                 resf = dwarf_create_cie_from_start(dbg,
466                     cieptr_val,
467                     section_ptr,
468                     section_index,
469                     section_length,
470                     section_ptr_end,
471                     cie_id_value,
472                     cie_count,
473                     use_gnu_cie_calc,
474                     &cie_ptr_to_use,
475                     error);
476                 if (resf == DW_DLV_ERROR) {
477                     dealloc_fde_cie_list_internal(head_fde_ptr,
478                         head_cie_ptr);
479                     return resf;
480                 } else if (resf == DW_DLV_NO_ENTRY) {
481                     return resf;
482                 }
483                 ++cie_count;
484                 chain_up_cie(cie_ptr_to_use, &head_cie_ptr,
485                     &tail_cie_ptr);
486                 cur_cie_ptr = tail_cie_ptr;
487 
488             } else {
489                 /* DW_DLV_ERROR */
490                 return resf;
491             }
492 
493             resf = dwarf_create_fde_from_after_start(dbg,
494                 &prefix,
495                 section_ptr,
496                 frame_ptr,
497                 section_ptr_end,
498                 use_gnu_cie_calc,
499                 cie_ptr_to_use,
500                 &fde_ptr_to_use,
501                 error);
502             if (resf == DW_DLV_ERROR) {
503                 dealloc_fde_cie_list_internal(head_fde_ptr,
504                     head_cie_ptr);
505                 return resf;
506             } else if (resf == DW_DLV_NO_ENTRY) {
507                 /* impossible. */
508                 return resf;
509             }
510             chain_up_fde(fde_ptr_to_use, &head_fde_ptr, &cur_fde_ptr);
511             fde_count++;
512             /* ASSERT: DW_DLV_OK. */
513             frame_ptr = cur_fde_ptr->fd_fde_start +
514                 cur_fde_ptr->fd_length +
515                 cur_fde_ptr->fd_length_size +
516                 cur_fde_ptr->fd_extension_size;
517             if (frame_ptr  <  fde_ptr_to_use->fd_fde_instr_start) {
518                 /*  Sanity check. With a really short fde instruction
519                     set and address_size we think is 8
520                     as it is ELF64 (but is
521                     really 4, as in DWARF{2,3} where we have
522                     no FDE address_size) we emit an error.
523                     This error means things will not go well. */
524                 dealloc_fde_cie_list_internal(head_fde_ptr,
525                     head_cie_ptr);
526                 _dwarf_error(dbg,error,
527                     DW_DLE_DEBUG_FRAME_POSSIBLE_ADDRESS_BOTCH);
528                 return DW_DLV_ERROR;
529             }
530             continue;
531         }
532     }
533     /*  Now build list of CIEs from the list. If there are no CIEs
534         there should be no FDEs. */
535     if (cie_count > 0) {
536         cie_list_ptr = (Dwarf_Cie *)
537             _dwarf_get_alloc(dbg, DW_DLA_LIST, cie_count);
538     } else {
539         if (fde_count > 0) {
540             dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr);
541             _dwarf_error(dbg, error, DW_DLE_ORPHAN_FDE);
542             return DW_DLV_ERROR;
543         }
544         dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr);
545         return DW_DLV_NO_ENTRY;
546     }
547     if (cie_list_ptr == NULL) {
548         dealloc_fde_cie_list_internal(head_fde_ptr, head_cie_ptr);
549         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
550         return DW_DLV_ERROR;
551     }
552     if (!head_cie_ptr) {
553         /*  Should be impossible. */
554         _dwarf_error(dbg, error,DW_DLE_DEBUGFRAME_ERROR);
555         return DW_DLV_ERROR;
556     }
557     cur_cie_ptr = head_cie_ptr;
558     for (i = 0; i < cie_count; i++) {
559         *(cie_list_ptr + i) = cur_cie_ptr;
560         cur_cie_ptr = cur_cie_ptr->ci_next;
561     }
562 
563     /*  Now build array of FDEs from the list.
564         With orphan CIEs (meaning no FDEs)
565         lets not return DW_DLV_NO_ENTRY */
566     if (fde_count > 0) {
567         fde_list_ptr = (Dwarf_Fde *)
568             _dwarf_get_alloc(dbg, DW_DLA_LIST, fde_count);
569     }
570 
571     /* It is ok if fde_list_ptr is NULL, we just have no fdes. */
572     cur_fde_ptr = head_fde_ptr;
573     for (i = 0; i < fde_count; i++) {
574         *(fde_list_ptr + i) = cur_fde_ptr;
575         cur_fde_ptr = cur_fde_ptr->fd_next;
576     }
577 
578 
579     /* Return arguments. */
580     *cie_data = cie_list_ptr;
581     *cie_element_count = cie_count;
582 
583     *fde_data = fde_list_ptr;
584     *fde_element_count = fde_count;
585     if (use_gnu_cie_calc) {
586         dbg->de_fde_data_eh = fde_list_ptr;
587         dbg->de_fde_count_eh = fde_count;
588         dbg->de_cie_data_eh = cie_list_ptr;
589         dbg->de_cie_count_eh = cie_count;
590     } else {
591         dbg->de_fde_data = fde_list_ptr;
592         dbg->de_fde_count = fde_count;
593         dbg->de_cie_data = cie_list_ptr;
594         dbg->de_cie_count = cie_count;
595     }
596 
597     /*  Sort the list by the address so that dwarf_get_fde_at_pc() can
598         binary search this list.  */
599     if (fde_count > 0) {
600         qsort((void *) fde_list_ptr, fde_count, sizeof(Dwarf_Ptr),
601             qsort_compare);
602     }
603 
604     return (DW_DLV_OK);
605 }
606 
607 /*  Internal function, not called by consumer code.
608     'prefix' has accumulated the info up thru the cie-id
609     and now we consume the rest and build a Dwarf_Cie_s structure.
610 */
611 int
612 dwarf_create_cie_from_after_start(Dwarf_Debug dbg,
613     struct cie_fde_prefix_s *prefix,
614     Dwarf_Small * section_pointer,
615     Dwarf_Small * frame_ptr,
616     Dwarf_Small * section_ptr_end,
617     Dwarf_Unsigned cie_count,
618     int use_gnu_cie_calc,
619     Dwarf_Cie * cie_ptr_out,
620     Dwarf_Error * error)
621 {
622     Dwarf_Cie new_cie = 0;
623 
624     /*  egcs-1.1.2 .eh_frame uses 0 as the distinguishing id. sgi uses
625         -1 (in .debug_frame). .eh_frame not quite identical to
626         .debug_frame */
627     /*  We here default the address size as it is not present
628         in DWARF2 or DWARF3 cie data, below we set it right if
629         it is present. */
630     Dwarf_Half address_size = dbg->de_pointer_size;
631     Dwarf_Small *augmentation = 0;
632     Dwarf_Half segment_size = 0;
633     Dwarf_Signed data_alignment_factor = -1;
634     Dwarf_Unsigned code_alignment_factor = 4;
635     Dwarf_Unsigned return_address_register = 31;
636     int local_length_size = 0;
637     Dwarf_Unsigned leb128_length = 0;
638     Dwarf_Unsigned cie_aug_data_len = 0;
639     Dwarf_Small *cie_aug_data = 0;
640     Dwarf_Addr gnu_personality_handler_addr = 0;
641     unsigned char gnu_personality_handler_encoding = 0;
642     unsigned char gnu_lsda_encoding = 0;
643     unsigned char gnu_fde_begin_encoding = 0;
644     int res = 0;
645     Dwarf_Small version = 0;
646 
647 
648     enum Dwarf_augmentation_type augt = aug_unknown;
649 
650     /*  This is a CIE, Common Information Entry: See the dwarf spec,
651         section 6.4.1 */
652     if (frame_ptr >= section_ptr_end) {
653         _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);
654         return DW_DLV_ERROR;
655     }
656     version = *(Dwarf_Small *) frame_ptr;
657 
658     if ((frame_ptr+2) >= section_ptr_end) {
659         _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);
660         return DW_DLV_ERROR;
661     }
662 
663     frame_ptr++;
664     if (version != DW_CIE_VERSION && version != DW_CIE_VERSION3 &&
665         version != DW_CIE_VERSION4 && version != DW_CIE_VERSION5) {
666         _dwarf_error(dbg, error, DW_DLE_FRAME_VERSION_BAD);
667         return (DW_DLV_ERROR);
668     }
669 
670     augmentation = frame_ptr;
671 
672     res = _dwarf_check_string_valid(dbg,section_pointer,
673         frame_ptr,section_ptr_end,
674         DW_DLE_AUGMENTATION_STRING_OFF_END,error);
675     if (res != DW_DLV_OK) {
676         return res;
677     }
678     frame_ptr = frame_ptr + strlen((char *) frame_ptr) + 1;
679     if (frame_ptr  >= section_ptr_end) {
680         _dwarf_error_string(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD,
681             "DW_DLE_DEBUG_FRAME_LENGTH_BAD: following any "
682             "augmentation field we have run off the end of the section "
683             "with the CIE incomplete.  Corrupt Dwarf");
684         return DW_DLV_ERROR;
685     }
686     augt = _dwarf_get_augmentation_type(dbg,
687         augmentation, use_gnu_cie_calc);
688     if (augt == aug_eh) {
689         /* REFERENCED *//* Not used in this instance */
690         UNUSEDARG Dwarf_Unsigned exception_table_addr;
691 
692         if ((frame_ptr+local_length_size)  >= section_ptr_end) {
693             _dwarf_error_string(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD,
694                 "DW_DLE_DEBUG_FRAME_LENGTH_BAD: following "
695                 "type field we have run off the end of the section "
696                 "with the CIE incomplete.  Corrupt Dwarf");
697             return DW_DLV_ERROR;
698         }
699         /* this is per egcs-1.1.2 as on RH 6.0 */
700         READ_UNALIGNED_CK(dbg, exception_table_addr,
701             Dwarf_Unsigned, frame_ptr, local_length_size,
702             error,section_ptr_end);
703         frame_ptr += local_length_size;
704     }
705     {
706         Dwarf_Unsigned lreg = 0;
707         unsigned long size = 0;
708 
709         if (version == DW_CIE_VERSION4) {
710             if ((frame_ptr+2)  >= section_ptr_end) {
711                 _dwarf_error_string(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD,
712                     "DW_DLE_DEBUG_FRAME_LENGTH_BAD: "
713                     "We would run off the end of the section "
714                     "in a DWARF4 cie header.  Corrupt Dwarf");
715                 return DW_DLV_ERROR;
716             }
717             address_size = *((unsigned char *)frame_ptr);
718             if (address_size  <  1) {
719                 _dwarf_error_string(dbg, error, DW_DLE_ADDRESS_SIZE_ZERO,
720                     "DW_DLE_ADDRESS_SIZE_ZERO: bad addres size "
721                     "for a DWARF4 cie header");
722                 return (DW_DLV_ERROR);
723             }
724             if (address_size  > sizeof(Dwarf_Addr)) {
725                 _dwarf_create_address_size_dwarf_error(dbg,
726                     error,address_size,
727                     DW_DLE_ADDRESS_SIZE_ERROR,
728                     "DW_DLE_ADDRESS_SIZE_ERROR..:");
729                 return DW_DLV_ERROR;
730             }
731             if ((frame_ptr+2)  >= section_ptr_end) {
732                 _dwarf_error_string(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD,
733                     "DW_DLE_DEBUG_FRAME_LENGTH_BAD: Running off the end "
734                     " of a CIE header. Corrupt DWARF4");
735                 return DW_DLV_ERROR;
736             }
737             ++frame_ptr;
738             segment_size = *((unsigned char *)frame_ptr);
739             ++frame_ptr;
740             if (segment_size  > sizeof(Dwarf_Addr)) {
741                 _dwarf_error(dbg, error, DW_DLE_SEGMENT_SIZE_BAD);
742                 return (DW_DLV_ERROR);
743             }
744         }
745 
746         /* Not a great test. But the DECODE* do checking so ok.  */
747         if ((frame_ptr+2)  >= section_ptr_end) {
748             _dwarf_error_string(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD,
749                 "DW_DLE_DEBUG_FRAME_LENGTH_BAD: Running off the end "
750                 " of a CIE header before the code alignment value "
751                 "read. Corrupt DWARF");
752             return DW_DLV_ERROR;
753         }
754         DECODE_LEB128_UWORD_CK(frame_ptr, lreg,dbg,error,section_ptr_end);
755         code_alignment_factor = (Dwarf_Unsigned) lreg;
756         res = (Dwarf_Signed) _dwarf_decode_s_leb128_chk(frame_ptr,
757             &leb128_length,&data_alignment_factor,section_ptr_end);
758         if(res != DW_DLV_OK) {
759             return res;
760         }
761         frame_ptr = frame_ptr + leb128_length;
762         /* Not a great test. FIXME */
763         if ((frame_ptr+1)  >= section_ptr_end) {
764             _dwarf_error_string(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD,
765                 "DW_DLE_DEBUG_FRAME_LENGTH_BAD: Running off the end "
766                 "of a CIE header before the return address register "
767                 "number read. Corrupt DWARF");
768 
769             return DW_DLV_ERROR;
770         }
771         res = _dwarf_get_return_address_reg(frame_ptr, version,
772             dbg,section_ptr_end, &size,&return_address_register,error);
773         if(res != DW_DLV_OK) {
774             return res;
775         }
776         if (return_address_register > dbg->de_frame_reg_rules_entry_count) {
777             _dwarf_error(dbg, error, DW_DLE_CIE_RET_ADDR_REG_ERROR);
778             return (DW_DLV_ERROR);
779         }
780         frame_ptr += size;
781         if ((frame_ptr)  > section_ptr_end) {
782             _dwarf_error_string(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD,
783                 "DW_DLE_DEBUG_FRAME_LENGTH_BAD: Past the end "
784                 "of a CIE header before reading the augmentation string."
785                 " Corrupt DWARF");
786             return DW_DLV_ERROR;
787         }
788     }
789     switch (augt) {
790     case aug_empty_string:
791         break;
792     case aug_irix_mti_v1:
793         break;
794     case aug_irix_exception_table:{
795         Dwarf_Unsigned lreg = 0;
796         Dwarf_Unsigned length_of_augmented_fields;
797 
798         /* Decode the length of augmented fields. */
799         DECODE_LEB128_UWORD_CK(frame_ptr, lreg,dbg,error,section_ptr_end);
800         length_of_augmented_fields = (Dwarf_Unsigned) lreg;
801         /* set the frame_ptr to point at the instruction start. */
802         frame_ptr += length_of_augmented_fields;
803         }
804         break;
805 
806     case aug_eh:{
807         int err = 0;
808         unsigned long increment = 0;
809 
810         if (!use_gnu_cie_calc) {
811             /* This should be impossible. */
812             _dwarf_error(dbg, error,DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
813             return DW_DLV_ERROR;
814         }
815 
816         err = get_gcc_eh_augmentation(dbg, frame_ptr, &increment,
817             augt,
818             section_ptr_end,
819             (char *) augmentation,error);
820         if (err == DW_DLV_ERROR) {
821             _dwarf_error(dbg, error,DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
822             return DW_DLV_ERROR;
823         }
824         frame_ptr += increment;
825         }
826         break;
827     case aug_gcc_eh_z:{
828         /*  Here we have Augmentation Data Length (uleb128) followed
829             by Augmentation Data bytes (not a string). */
830         int resz = DW_DLV_ERROR;
831         Dwarf_Unsigned adlen = 0;
832 
833         /* Not a great test. FIXME */
834         if ((frame_ptr+1)  > section_ptr_end) {
835             _dwarf_error_string(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD,
836                 "DW_DLE_AUG_DATA_LENGTH_BAD: The "
837                 "gcc .eh_frame augmentation data "
838                 "cannot be read. Out of room in the section."
839                 " Corrupt DWARF.");
840             return DW_DLV_ERROR;
841         }
842         DECODE_LEB128_UWORD_CK(frame_ptr, adlen,
843             dbg,error,section_ptr_end);
844         cie_aug_data_len = adlen;
845         cie_aug_data = frame_ptr;
846         if (adlen) {
847             Dwarf_Small *cie_aug_data_end = cie_aug_data+adlen;
848             if (cie_aug_data_end < cie_aug_data ||
849                 cie_aug_data_end > section_ptr_end) {
850                 dwarfstring m;
851 
852                 dwarfstring_constructor(&m);
853                 dwarfstring_append_printf_u(&m,
854                     "DW_DLE_AUG_DATA_LENGTH_BAD: The "
855                     "gcc .eh_frame augmentation data "
856                     "length of %" DW_PR_DUu " is too long to"
857                     " fit in the section.",adlen);
858                 _dwarf_error_string(dbg, error,
859                     DW_DLE_AUG_DATA_LENGTH_BAD,
860                     dwarfstring_string(&m));
861                 dwarfstring_destructor(&m);
862                 return DW_DLV_ERROR;
863             }
864         }
865         resz = gnu_aug_encodings(dbg,
866             (char *) augmentation,
867             cie_aug_data,
868             cie_aug_data_len,
869             address_size,
870             &gnu_personality_handler_encoding,
871             &gnu_lsda_encoding,
872             &gnu_fde_begin_encoding,
873             &gnu_personality_handler_addr,
874             error);
875         if (resz != DW_DLV_OK) {
876             _dwarf_error(dbg, error,
877                 DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
878             return resz;
879         }
880         frame_ptr += adlen;
881         }
882         break;
883     case aug_armcc:
884         break;
885     default:{
886         /*  We do not understand the augmentation string. No
887             assumption can be made about any fields other than what
888             we have already read. */
889         frame_ptr = prefix->cf_start_addr +
890             prefix->cf_length + prefix->cf_local_length_size
891             + prefix->cf_local_extension_size;
892         /*  FIX -- What are the values of data_alignment_factor,
893             code_alignement_factor, return_address_register and
894             instruction start? They were clearly uninitalized in the
895             previous version and I am leaving them the same way. */
896         }
897         if ((frame_ptr)  > section_ptr_end) {
898             _dwarf_error_string(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD,
899                 "DW_DLE_DEBUG_FRAME_LENGTH_BAD: "
900                 "Reading an unknown type of augmentation string "
901                 "run off the end of the section. Corrupt DWARF.");
902             return DW_DLV_ERROR;
903         }
904         break;
905     }                           /* End switch on augmentation type. */
906 
907     new_cie = (Dwarf_Cie) _dwarf_get_alloc(dbg, DW_DLA_CIE, 1);
908     if (new_cie == NULL) {
909         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
910         return (DW_DLV_ERROR);
911     }
912 
913     new_cie->ci_cie_version_number = version;
914     new_cie->ci_initial_table = NULL;
915     new_cie->ci_length = (Dwarf_Unsigned) prefix->cf_length;
916     new_cie->ci_length_size = prefix->cf_local_length_size;
917     new_cie->ci_extension_size = prefix->cf_local_extension_size;
918     new_cie->ci_augmentation = (char *) augmentation;
919 
920     new_cie->ci_data_alignment_factor =
921         (Dwarf_Sbyte) data_alignment_factor;
922     new_cie->ci_code_alignment_factor =
923         (Dwarf_Small) code_alignment_factor;
924     new_cie->ci_return_address_register = return_address_register;
925     new_cie->ci_cie_start = prefix->cf_start_addr;
926 
927     if ( frame_ptr > section_ptr_end) {
928         _dwarf_error(dbg, error, DW_DLE_DF_FRAME_DECODING_ERROR);
929         return (DW_DLV_ERROR);
930     }
931     new_cie->ci_cie_instr_start = frame_ptr;
932     new_cie->ci_dbg = dbg;
933     new_cie->ci_augmentation_type = augt;
934     new_cie->ci_gnu_eh_augmentation_len = cie_aug_data_len;
935     new_cie->ci_gnu_eh_augmentation_bytes = cie_aug_data;
936     new_cie->ci_gnu_personality_handler_encoding =
937         gnu_personality_handler_encoding;
938     new_cie->ci_gnu_personality_handler_addr =
939         gnu_personality_handler_addr;
940     new_cie->ci_gnu_lsda_encoding = gnu_lsda_encoding;
941     new_cie->ci_gnu_fde_begin_encoding = gnu_fde_begin_encoding;
942 
943     new_cie->ci_index = cie_count;
944     new_cie->ci_section_ptr = prefix->cf_section_ptr;
945     new_cie->ci_section_end = section_ptr_end;
946     new_cie->ci_cie_end = new_cie->ci_cie_start + new_cie->ci_length +
947         new_cie->ci_length_size+ new_cie->ci_extension_size;
948     if ( new_cie->ci_cie_end > section_ptr_end) {
949         _dwarf_error(dbg, error, DW_DLE_DF_FRAME_DECODING_ERROR);
950         return (DW_DLV_ERROR);
951     }
952 
953     /* The Following new in DWARF4 */
954     new_cie->ci_address_size = address_size;
955     new_cie->ci_segment_size = segment_size;
956     validate_length(dbg,new_cie,new_cie->ci_length,
957         new_cie->ci_length_size, new_cie->ci_extension_size,
958         new_cie->ci_section_ptr,
959         new_cie->ci_cie_start,"cie");
960 
961     *cie_ptr_out = new_cie;
962     return DW_DLV_OK;
963 
964 }
965 
966 
967 /*  Internal function, not called by consumer code.
968     'prefix' has accumulated the info up thru the cie-id
969     and now we consume the rest and build a Dwarf_Fde_s structure.
970     Can be called with cie_ptr_in NULL from dwarf_frame.c  */
971 
972 int
973 dwarf_create_fde_from_after_start(Dwarf_Debug dbg,
974     struct cie_fde_prefix_s *prefix,
975     Dwarf_Small * section_pointer,
976     Dwarf_Small * frame_ptr,
977     Dwarf_Small * section_ptr_end,
978     int use_gnu_cie_calc,
979     Dwarf_Cie cie_ptr_in,
980     Dwarf_Fde * fde_ptr_out,
981     Dwarf_Error * error)
982 {
983     Dwarf_Fde new_fde = 0;
984     Dwarf_Cie cieptr = 0;
985     Dwarf_Small *saved_frame_ptr = 0;
986 
987     Dwarf_Small *initloc = frame_ptr;
988     Dwarf_Signed offset_into_exception_tables
989         = (Dwarf_Signed) DW_DLX_NO_EH_OFFSET;
990     Dwarf_Small *fde_aug_data = 0;
991     Dwarf_Unsigned fde_aug_data_len = 0;
992     Dwarf_Addr cie_base_offset = prefix->cf_cie_id;
993     Dwarf_Addr initial_location = 0;    /* must be min de_pointer_size
994         bytes in size */
995     Dwarf_Addr address_range = 0;       /* must be min de_pointer_size
996         bytes in size */
997     Dwarf_Half address_size = 0;
998     Dwarf_Unsigned eh_table_value = 0;
999     Dwarf_Bool eh_table_value_set = FALSE;
1000     /* Temporary assumption.  */
1001     enum Dwarf_augmentation_type augt = aug_empty_string;
1002 
1003     if (cie_ptr_in) {
1004         cieptr = cie_ptr_in;
1005         address_size = cieptr->ci_address_size;
1006         augt = cieptr->ci_augmentation_type;
1007     }
1008 
1009     if (augt == aug_gcc_eh_z) {
1010         /*  If z augmentation this is eh_frame, and initial_location and
1011             address_range in the FDE are read according to the CIE
1012             augmentation string instructions.  */
1013 
1014         {
1015             Dwarf_Small *fp_updated = 0;
1016             int res = read_encoded_ptr(dbg,
1017                 section_pointer,
1018                 frame_ptr,
1019                 cieptr-> ci_gnu_fde_begin_encoding,
1020                 section_ptr_end,
1021                 address_size,
1022                 &initial_location,
1023                 &fp_updated,error);
1024             if (res != DW_DLV_OK) {
1025                 return res;
1026             }
1027             frame_ptr = fp_updated;
1028             /*  For the address-range it makes no sense to be
1029                 pc-relative, so we turn it off with a section_pointer of
1030                 NULL. Masking off DW_EH_PE_pcrel from the
1031                 ci_gnu_fde_begin_encoding in this call would also work
1032                 to turn off DW_EH_PE_pcrel. */
1033             res = read_encoded_ptr(dbg, (Dwarf_Small *) NULL,
1034                 frame_ptr,
1035                 cieptr->ci_gnu_fde_begin_encoding,
1036                 section_ptr_end,
1037                 address_size,
1038                 &address_range, &fp_updated,error);
1039             if (res != DW_DLV_OK) {
1040                 return res;
1041             }
1042             frame_ptr = fp_updated;
1043         }
1044         {
1045             Dwarf_Unsigned adlen = 0;
1046 
1047             DECODE_LEB128_UWORD_CK(frame_ptr, adlen,
1048                 dbg,error,section_ptr_end);
1049             fde_aug_data_len = adlen;
1050             fde_aug_data = frame_ptr;
1051             frame_ptr += adlen;
1052             if (adlen) {
1053                 if (frame_ptr < fde_aug_data ||
1054                     frame_ptr >= section_ptr_end ) {
1055                     dwarfstring m;
1056 
1057                     dwarfstring_constructor(&m);
1058                     dwarfstring_append_printf_u(&m,
1059                         "DW_DLE_AUG_DATA_LENGTH_BAD: The "
1060                         "gcc .eh_frame augmentation data "
1061                         "length of %" DW_PR_DUu " is too long to"
1062                         " fit in the section.",adlen);
1063                     _dwarf_error_string(dbg, error,
1064                         DW_DLE_AUG_DATA_LENGTH_BAD,
1065                         dwarfstring_string(&m));
1066                     dwarfstring_destructor(&m);
1067                     return DW_DLV_ERROR;
1068                 }
1069             }
1070         }
1071 
1072     } else {
1073         if ((frame_ptr + 2*address_size) > section_ptr_end) {
1074             _dwarf_error(dbg,error,DW_DLE_DEBUG_FRAME_LENGTH_BAD);
1075             return DW_DLV_ERROR;
1076         }
1077         READ_UNALIGNED_CK(dbg, initial_location, Dwarf_Addr,
1078             frame_ptr, address_size,
1079             error,section_ptr_end);
1080         frame_ptr += address_size;
1081         READ_UNALIGNED_CK(dbg, address_range, Dwarf_Addr,
1082             frame_ptr, address_size,
1083             error,section_ptr_end);
1084         frame_ptr += address_size;
1085     }
1086     switch (augt) {
1087     case aug_irix_mti_v1:
1088     case aug_empty_string:
1089         break;
1090     case aug_irix_exception_table:{
1091         Dwarf_Unsigned lreg = 0;
1092         Dwarf_Unsigned length_of_augmented_fields = 0;
1093 
1094         DECODE_LEB128_UWORD_CK(frame_ptr, lreg,
1095             dbg,error,section_ptr_end);
1096         length_of_augmented_fields = (Dwarf_Unsigned) lreg;
1097 
1098         saved_frame_ptr = frame_ptr;
1099         /*  The first word is an offset into exception tables.
1100             Defined as a 32bit offset even for CC -64. */
1101         if ((frame_ptr + DWARF_32BIT_SIZE) > section_ptr_end) {
1102             _dwarf_error(dbg,error,DW_DLE_DEBUG_FRAME_LENGTH_BAD);
1103             return DW_DLV_ERROR;
1104         }
1105         READ_UNALIGNED_CK(dbg, offset_into_exception_tables,
1106             Dwarf_Addr, frame_ptr, DWARF_32BIT_SIZE,
1107             error,section_ptr_end);
1108         SIGN_EXTEND(offset_into_exception_tables,
1109             DWARF_32BIT_SIZE);
1110         frame_ptr = saved_frame_ptr + length_of_augmented_fields;
1111         }
1112         break;
1113     case aug_eh:{
1114 
1115         if (!use_gnu_cie_calc) {
1116             /* This should be impossible. */
1117             _dwarf_error(dbg, error,DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
1118             return DW_DLV_ERROR;
1119         }
1120 
1121         /* gnu eh fde case. we do not need to do anything */
1122         /*REFERENCED*/ /* Not used in this instance of the macro */
1123         if ((frame_ptr + address_size) > section_ptr_end) {
1124             _dwarf_error(dbg,error,DW_DLE_DEBUG_FRAME_LENGTH_BAD);
1125             return DW_DLV_ERROR;
1126         }
1127         READ_UNALIGNED_CK(dbg, eh_table_value,
1128             Dwarf_Unsigned, frame_ptr,
1129             address_size,
1130             error,section_ptr_end);
1131         eh_table_value_set = TRUE;
1132         frame_ptr += address_size;
1133         }
1134         break;
1135 
1136     case aug_gcc_eh_z:{
1137         /*  The Augmentation Data Length is here, followed by the
1138             Augmentation Data bytes themselves. */
1139         }
1140         break;
1141     case aug_armcc:
1142         break;
1143     case aug_past_last:
1144         break;
1145 
1146     case aug_metaware: /* No special fields. See dwarf_util.h */
1147         break;
1148 
1149     case aug_unknown:
1150         _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
1151         return DW_DLV_ERROR;
1152     }                           /* End switch on augmentation type */
1153     if ( frame_ptr > section_ptr_end) {
1154         _dwarf_error(dbg, error, DW_DLE_DF_FRAME_DECODING_ERROR);
1155         return (DW_DLV_ERROR);
1156     }
1157 
1158     new_fde = (Dwarf_Fde) _dwarf_get_alloc(dbg, DW_DLA_FDE, 1);
1159     if (new_fde == NULL) {
1160         _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
1161         return (DW_DLV_ERROR);
1162     }
1163 
1164     new_fde->fd_length = prefix->cf_length;
1165     new_fde->fd_length_size = prefix->cf_local_length_size;
1166     new_fde->fd_extension_size = prefix->cf_local_extension_size;
1167     new_fde->fd_is_eh = use_gnu_cie_calc;
1168     new_fde->fd_cie_offset = cie_base_offset;
1169     if (cieptr) {
1170         new_fde->fd_cie_index = cieptr->ci_index;
1171     }
1172     new_fde->fd_cie = cieptr;
1173     new_fde->fd_initial_location = initial_location;
1174     new_fde->fd_initial_loc_pos = initloc;
1175     new_fde->fd_address_range = address_range;
1176     new_fde->fd_fde_start = prefix->cf_start_addr;
1177 
1178     new_fde->fd_fde_instr_start = frame_ptr;
1179     new_fde->fd_fde_end = prefix->cf_start_addr +
1180         prefix->cf_length +  prefix->cf_local_length_size  +
1181         prefix->cf_local_extension_size;
1182     if ( new_fde->fd_fde_end > section_ptr_end) {
1183         _dwarf_error(dbg, error, DW_DLE_DF_FRAME_DECODING_ERROR);
1184         return (DW_DLV_ERROR);
1185     }
1186 
1187     new_fde->fd_dbg = dbg;
1188     new_fde->fd_offset_into_exception_tables =
1189         offset_into_exception_tables;
1190     new_fde->fd_eh_table_value = eh_table_value;
1191     new_fde->fd_eh_table_value_set = eh_table_value_set;
1192 
1193     new_fde->fd_section_ptr = prefix->cf_section_ptr;
1194     new_fde->fd_section_index = prefix->cf_section_index;
1195     new_fde->fd_section_length = prefix->cf_section_length;
1196     new_fde->fd_section_end = section_ptr_end;
1197 
1198     if (augt == aug_gcc_eh_z) {
1199         new_fde->fd_gnu_eh_aug_present = TRUE;
1200     }
1201     new_fde->fd_gnu_eh_augmentation_bytes = fde_aug_data;
1202     new_fde->fd_gnu_eh_augmentation_len = fde_aug_data_len;
1203     validate_length(dbg,cieptr,new_fde->fd_length,
1204         new_fde->fd_length_size, new_fde->fd_extension_size,
1205         new_fde->fd_section_ptr,new_fde->fd_fde_start,"fde");
1206     *fde_ptr_out = new_fde;
1207     return DW_DLV_OK;
1208 }
1209 
1210 /*  Read in the common cie/fde prefix, including reading
1211     the cie-value which shows which this is: cie or fde.  */
1212 int
1213 dwarf_read_cie_fde_prefix(Dwarf_Debug dbg,
1214     Dwarf_Small * frame_ptr_in,
1215     Dwarf_Small * section_ptr_in,
1216     Dwarf_Unsigned section_index_in,
1217     Dwarf_Unsigned section_length_in,
1218     struct cie_fde_prefix_s *data_out,
1219     Dwarf_Error * error)
1220 {
1221     Dwarf_Unsigned length = 0;
1222     int local_length_size = 0;
1223     int local_extension_size = 0;
1224     Dwarf_Small *frame_ptr = frame_ptr_in;
1225     Dwarf_Small *cie_ptr_addr = 0;
1226     Dwarf_Unsigned cie_id = 0;
1227     Dwarf_Small *section_end = section_ptr_in + section_length_in;
1228 
1229     if(section_end < (frame_ptr +4)) {
1230         dwarfstring m;
1231         Dwarf_Unsigned u = (Dwarf_Unsigned)(uintptr_t)(frame_ptr+4) -
1232             (Dwarf_Unsigned)(uintptr_t)section_end;
1233 
1234         dwarfstring_constructor(&m);
1235         dwarfstring_append_printf_u(&m,
1236             "DW_DLE_DEBUG_FRAME_LENGTH_BAD: "
1237             "Reading the cie/fde prefix would "
1238             "put us %u bytes past the end of the "
1239             "frame section.  Corrupt Dwarf.",u);
1240         _dwarf_error_string(dbg,error,DW_DLE_DEBUG_FRAME_LENGTH_BAD,
1241             dwarfstring_string(&m));
1242         dwarfstring_destructor(&m);
1243         return DW_DLV_ERROR;
1244     }
1245     /* READ_AREA_LENGTH updates frame_ptr for consumed bytes */
1246     READ_AREA_LENGTH_CK(dbg, length, Dwarf_Unsigned,
1247         frame_ptr, local_length_size,
1248         local_extension_size,error,
1249         section_length_in,section_end);
1250 
1251     if (length == 0) {
1252         /*  nul bytes at end of section, seen at end of egcs eh_frame
1253             sections (in a.out). Take this as meaning no more CIE/FDE
1254             data. We should be very close to end of section. */
1255         return DW_DLV_NO_ENTRY;
1256     }
1257     if((frame_ptr + local_length_size) >= section_end) {
1258         _dwarf_error(dbg,error,DW_DLE_DEBUG_FRAME_LENGTH_BAD);
1259         return DW_DLV_ERROR;
1260     }
1261 
1262     cie_ptr_addr = frame_ptr;
1263     READ_UNALIGNED_CK(dbg, cie_id, Dwarf_Unsigned,
1264         frame_ptr, local_length_size,error,section_end);
1265     SIGN_EXTEND(cie_id, local_length_size);
1266     frame_ptr += local_length_size;
1267 
1268     data_out->cf_start_addr = frame_ptr_in;
1269     data_out->cf_addr_after_prefix = frame_ptr;
1270 
1271     data_out->cf_length = length;
1272     if (length > section_length_in) {
1273         _dwarf_error(dbg,error,DW_DLE_DEBUG_FRAME_LENGTH_BAD);
1274         return DW_DLV_ERROR;
1275     }
1276     if (cie_ptr_addr+length > section_end) {
1277         _dwarf_error(dbg,error,DW_DLE_DEBUG_FRAME_LENGTH_BAD);
1278         return DW_DLV_ERROR;
1279     }
1280     data_out->cf_local_length_size = local_length_size;
1281     data_out->cf_local_extension_size = local_extension_size;
1282 
1283     /*  We do not know if it is a CIE or FDE id yet.
1284         How we check and what it means
1285         depends whether it is .debug_frame
1286         or .eh_frame. */
1287     data_out->cf_cie_id = cie_id;
1288 
1289     /*  The address of the CIE_id  or FDE_id value in memory.  */
1290     data_out->cf_cie_id_addr = cie_ptr_addr;
1291 
1292     data_out->cf_section_ptr = section_ptr_in;
1293     data_out->cf_section_index = section_index_in;
1294     data_out->cf_section_length = section_length_in;
1295     return DW_DLV_OK;
1296 }
1297 
1298 /*  On various errors previously-allocated CIEs and FDEs
1299     must be cleaned up.
1300     This helps avoid leaks in case of errors.
1301 */
1302 static void
1303 dealloc_fde_cie_list_internal(Dwarf_Fde head_fde_ptr,
1304     Dwarf_Cie head_cie_ptr)
1305 {
1306     Dwarf_Fde curfde = 0;
1307     Dwarf_Cie curcie = 0;
1308     Dwarf_Fde nextfde = 0;
1309     Dwarf_Cie nextcie = 0;
1310 
1311     for (curfde = head_fde_ptr; curfde; curfde = nextfde) {
1312         nextfde = curfde->fd_next;
1313         dwarf_dealloc(curfde->fd_dbg, curfde, DW_DLA_FDE);
1314     }
1315     for (curcie = head_cie_ptr; curcie; curcie = nextcie) {
1316         Dwarf_Frame frame = curcie->ci_initial_table;
1317 
1318         nextcie = curcie->ci_next;
1319         if (frame)
1320             dwarf_dealloc(curcie->ci_dbg, frame, DW_DLA_FRAME);
1321         dwarf_dealloc(curcie->ci_dbg, curcie, DW_DLA_CIE);
1322     }
1323 }
1324 
1325 /*  Find the cie whose id value is given: the id
1326     value is, per DWARF2/3, an offset in the section.
1327     For .debug_frame, zero is a legal offset. For
1328     GNU .eh_frame it is not a legal offset.
1329     'cie_ptr' is a pointer into our section, not an offset. */
1330 static int
1331 dwarf_find_existing_cie_ptr(Dwarf_Small * cie_ptr,
1332     Dwarf_Cie cur_cie_ptr,
1333     Dwarf_Cie * cie_ptr_to_use_out,
1334     Dwarf_Cie head_cie_ptr)
1335 {
1336     Dwarf_Cie next = 0;
1337 
1338     if (cur_cie_ptr && cie_ptr == cur_cie_ptr->ci_cie_start) {
1339         /* Usually, we use the same cie again and again. */
1340         *cie_ptr_to_use_out = cur_cie_ptr;
1341         return DW_DLV_OK;
1342     }
1343     for (next = head_cie_ptr; next; next = next->ci_next) {
1344         if (cie_ptr == next->ci_cie_start) {
1345             *cie_ptr_to_use_out = next;
1346             return DW_DLV_OK;
1347         }
1348     }
1349     return DW_DLV_NO_ENTRY;
1350 }
1351 
1352 
1353 /*  We have a valid cie_ptr_val that has not been
1354     turned into an internal Cie yet. Do so now.
1355     Returns DW_DLV_OK or DW_DLV_ERROR, never
1356     DW_DLV_NO_ENTRY.
1357 
1358     'section_ptr'    - Points to first byte of section data.
1359     'section_length' - Length of the section, in bytes.
1360     'section_ptr_end'  - Points 1-past last byte of section data.  */
1361 static int
1362 dwarf_create_cie_from_start(Dwarf_Debug dbg,
1363     Dwarf_Small * cie_ptr_val,
1364     Dwarf_Small * section_ptr,
1365     Dwarf_Unsigned section_index,
1366     Dwarf_Unsigned section_length,
1367     Dwarf_Small * section_ptr_end,
1368     Dwarf_Unsigned cie_id_value,
1369     Dwarf_Unsigned cie_count,
1370     int use_gnu_cie_calc,
1371     Dwarf_Cie * cie_ptr_to_use_out,
1372     Dwarf_Error * error)
1373 {
1374     struct cie_fde_prefix_s prefix;
1375     int res = DW_DLV_ERROR;
1376     Dwarf_Small *frame_ptr = cie_ptr_val;
1377 
1378     if (frame_ptr < section_ptr || frame_ptr >= section_ptr_end) {
1379         _dwarf_error(dbg, error, DW_DLE_DEBUG_FRAME_LENGTH_BAD);
1380         return DW_DLV_ERROR;
1381     }
1382     /*  First read in the 'common prefix' to figure out what * we are to
1383         do with this entry. If it is not a cie * we are in big trouble. */
1384     memset(&prefix, 0, sizeof(prefix));
1385     res = dwarf_read_cie_fde_prefix(dbg, frame_ptr, section_ptr,
1386         section_index, section_length,
1387         &prefix, error);
1388     if (res == DW_DLV_ERROR) {
1389         return res;
1390     }
1391     if (res == DW_DLV_NO_ENTRY) {
1392         /* error. */
1393         _dwarf_error(dbg, error, DW_DLE_FRAME_CIE_DECODE_ERROR);
1394         return DW_DLV_ERROR;
1395 
1396     }
1397 
1398     if (prefix.cf_cie_id != cie_id_value) {
1399         _dwarf_error(dbg, error, DW_DLE_FRAME_CIE_DECODE_ERROR);
1400         return DW_DLV_ERROR;
1401     }
1402     frame_ptr = prefix.cf_addr_after_prefix;
1403     res = dwarf_create_cie_from_after_start(dbg,
1404         &prefix,
1405         section_ptr,
1406         frame_ptr,
1407         section_ptr_end,
1408         cie_count,
1409         use_gnu_cie_calc,
1410         cie_ptr_to_use_out, error);
1411     return res;
1412 
1413 }
1414 
1415 
1416 /* This is for gnu eh frames, the 'z' case.
1417    We find the letter involved
1418    Return the augmentation character and, if applicable,
1419    the personality routine address.
1420 
1421    personality_routine_out -
1422         if 'P' is augchar, is personality handler addr.
1423         Otherwise is not set.
1424    aug_data  - if 'P' points  to data space of the
1425    aug_data_len - length of areas aug_data points to.
1426 
1427 */
1428 
1429 /*  It is not clear if this is entirely correct. */
1430 static int
1431 gnu_aug_encodings(Dwarf_Debug dbg, char *augmentation,
1432     Dwarf_Small * aug_data, Dwarf_Unsigned aug_data_len,
1433     Dwarf_Half address_size,
1434     unsigned char *pers_hand_enc_out,
1435     unsigned char *lsda_enc_out,
1436     unsigned char *fde_begin_enc_out,
1437     Dwarf_Addr * gnu_pers_addr_out,
1438     Dwarf_Error * error)
1439 {
1440     char *nc = 0;
1441     Dwarf_Small *cur_aug_p = aug_data;
1442     Dwarf_Small *end_aug_p = aug_data + aug_data_len;
1443 
1444     for (nc = augmentation; *nc; ++nc) {
1445         char c = *nc;
1446 
1447         switch (c) {
1448         case 'z':
1449             /* Means that the augmentation data is present. */
1450             continue;
1451 
1452         case 'S':
1453             /*  Indicates this is a signal stack frame.
1454                 Debuggers have to do
1455                 special handling.  We don't need to do more than
1456                 print this flag at the right time, though
1457                 (see dwarfdump where it prints the augmentation
1458                 string).
1459                 A signal stack frame (in some OS's) can only be
1460                 unwound (backtraced) by knowing it is a signal
1461                 stack frame (perhaps by noticing the name of the
1462                 function for the stack frame if the name can be
1463                 found somehow) and figuring
1464                 out (or knowing) how the kernel and libc
1465                 pushed a structure
1466                 onto the stack and loading registers from that structure.
1467                 Totally different from normal stack unwinding.
1468                 This flag gives an unwinder a big leg up by
1469                 decoupling the 'hint: this is a stack frame'
1470                 from knowledge like
1471                 the function name (the name might be
1472                 unavailable at unwind time).
1473             */
1474             break;
1475 
1476         case 'L':
1477             if (cur_aug_p > end_aug_p) {
1478                 _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
1479                 return DW_DLV_ERROR;
1480             }
1481             *lsda_enc_out = *(unsigned char *) cur_aug_p;
1482             ++cur_aug_p;
1483             break;
1484         case 'R':
1485             /*  Followed by a one byte argument giving the
1486                 pointer encoding for the address pointers in the fde. */
1487             if (cur_aug_p >= end_aug_p) {
1488                 _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
1489                 return DW_DLV_ERROR;
1490             }
1491             *fde_begin_enc_out = *(unsigned char *) cur_aug_p;
1492             ++cur_aug_p;
1493             break;
1494         case 'P':{
1495             int res = DW_DLV_ERROR;
1496             Dwarf_Small *updated_aug_p = 0;
1497             unsigned char encoding = 0;
1498 
1499             if (cur_aug_p >= end_aug_p) {
1500                 _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
1501                 return DW_DLV_ERROR;
1502             }
1503             encoding = *(unsigned char *) cur_aug_p;
1504             *pers_hand_enc_out = encoding;
1505             ++cur_aug_p;
1506             if (cur_aug_p > end_aug_p) {
1507                 _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
1508                 return DW_DLV_ERROR;
1509             }
1510             /*  DW_EH_PE_pcrel makes no sense here, so we turn it
1511                 off via a section pointer of NULL. */
1512             res = read_encoded_ptr(dbg,
1513                 (Dwarf_Small *) NULL,
1514                 cur_aug_p,
1515                 encoding,
1516                 end_aug_p,
1517                 address_size,
1518                 gnu_pers_addr_out,
1519                 &updated_aug_p,
1520                 error);
1521             if (res != DW_DLV_OK) {
1522                 return res;
1523             }
1524             cur_aug_p = updated_aug_p;
1525             if (cur_aug_p > end_aug_p) {
1526                 _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
1527                 return DW_DLV_ERROR;
1528             }
1529             }
1530             break;
1531         default:
1532             _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
1533             return DW_DLV_ERROR;
1534 
1535         }
1536     }
1537     return DW_DLV_OK;
1538 }
1539 
1540 /*  Given augmentation character (the encoding) giving the
1541     address format, read the address from input_field
1542     and return an incremented value 1 past the input bytes of the
1543     address.
1544     Push the address read back thru the *addr pointer.
1545     See LSB (Linux Standard Base)  exception handling documents.  */
1546 static int
1547 read_encoded_ptr(Dwarf_Debug dbg,
1548     Dwarf_Small * section_pointer,
1549     Dwarf_Small * input_field,
1550     int gnu_encoding,
1551     Dwarf_Small * section_end,
1552     Dwarf_Half address_size,
1553     Dwarf_Unsigned * addr,
1554     Dwarf_Small ** input_field_updated,
1555     Dwarf_Error *error)
1556 {
1557     int value_type = gnu_encoding & 0xf;
1558     Dwarf_Small *input_field_original = input_field;
1559 
1560     if (gnu_encoding == 0xff) {
1561         /* There is no data here. */
1562 
1563         *addr = 0;
1564         *input_field_updated = input_field;
1565         /* Should we return DW_DLV_NO_ENTRY? */
1566         return DW_DLV_OK;
1567     }
1568     switch (value_type) {
1569     case DW_EH_PE_absptr:{
1570         /* value_type is zero. Treat as pointer size of the object.
1571         */
1572         Dwarf_Unsigned ret_value = 0;
1573 
1574         READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned,
1575             input_field, address_size,error,section_end);
1576         *addr = ret_value;
1577         *input_field_updated = input_field + address_size;
1578         }
1579         break;
1580     case DW_EH_PE_uleb128:{
1581         Dwarf_Unsigned val = 0;
1582 
1583         DECODE_LEB128_UWORD_CK(input_field,val,dbg,error,section_end);
1584         *addr = val;
1585         *input_field_updated = input_field;
1586         }
1587         break;
1588     case DW_EH_PE_udata2:{
1589         Dwarf_Unsigned ret_value = 0;
1590 
1591         READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned,
1592             input_field, 2,error,section_end);
1593         *addr = ret_value;
1594         *input_field_updated = input_field + 2;
1595         }
1596         break;
1597 
1598     case DW_EH_PE_udata4:{
1599         Dwarf_Unsigned ret_value = 0;
1600 
1601         READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned,
1602             input_field, DWARF_32BIT_SIZE,error,section_end);
1603         *addr = ret_value;
1604         *input_field_updated = input_field + DWARF_32BIT_SIZE;
1605         }
1606         break;
1607 
1608     case DW_EH_PE_udata8:{
1609         Dwarf_Unsigned ret_value = 0;
1610 
1611         /* ASSERT: sizeof(Dwarf_Unsigned) == 8 */
1612         READ_UNALIGNED_CK(dbg, ret_value, Dwarf_Unsigned,
1613             input_field, DWARF_64BIT_SIZE,error,section_end);
1614         *addr = ret_value;
1615         *input_field_updated = input_field +  DWARF_64BIT_SIZE;
1616         }
1617         break;
1618 
1619     case DW_EH_PE_sleb128:{
1620         Dwarf_Signed val = 0;
1621 
1622         DECODE_LEB128_SWORD_CK(input_field,val,dbg,error,section_end);
1623         *addr = (Dwarf_Unsigned) val;
1624         *input_field_updated = input_field;
1625         }
1626         break;
1627     case DW_EH_PE_sdata2:{
1628         Dwarf_Unsigned val = 0;
1629 
1630         READ_UNALIGNED_CK(dbg, val, Dwarf_Unsigned, input_field, 2,
1631             error,section_end);
1632         SIGN_EXTEND(val, 2);
1633         *addr = (Dwarf_Unsigned) val;
1634         *input_field_updated = input_field + 2;
1635         }
1636         break;
1637 
1638     case DW_EH_PE_sdata4:{
1639         Dwarf_Unsigned val = 0;
1640 
1641         READ_UNALIGNED_CK(dbg, val,
1642             Dwarf_Unsigned, input_field,
1643             DWARF_32BIT_SIZE,error,section_end);
1644         SIGN_EXTEND(val, DWARF_32BIT_SIZE);
1645         *addr = (Dwarf_Unsigned) val;
1646         *input_field_updated = input_field + DWARF_32BIT_SIZE;
1647         }
1648         break;
1649     case DW_EH_PE_sdata8:{
1650         Dwarf_Unsigned val = 0;
1651 
1652         /* ASSERT: sizeof(Dwarf_Unsigned) == 8 */
1653         READ_UNALIGNED_CK(dbg, val,
1654             Dwarf_Unsigned, input_field,
1655             DWARF_64BIT_SIZE,error,section_end);
1656         *addr = (Dwarf_Unsigned) val;
1657         *input_field_updated = input_field + DWARF_64BIT_SIZE;
1658         }
1659         break;
1660     default:
1661         _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
1662         return DW_DLV_ERROR;
1663 
1664     };
1665     /*  The ELF ABI for gnu does not document the meaning of
1666         DW_EH_PE_pcrel, which is awkward.  It apparently means the value
1667         we got above is pc-relative (meaning section-relative), so we
1668         adjust the value. Section_pointer may be null if it is known
1669         DW_EH_PE_pcrel cannot apply, such as for .debug_frame or for an
1670         address-range value. */
1671     if (section_pointer && ((gnu_encoding & 0x70) == DW_EH_PE_pcrel)) {
1672         /*  Address (*addr) above is pc relative with respect to a
1673             section. Add to the offset the base address (from elf) of
1674             section and the distance of the field we are reading from
1675             the section-beginning to get the actual address. */
1676         /*  ASSERT: input_field_original >= section_pointer */
1677         Dwarf_Unsigned distance =
1678             input_field_original - section_pointer;
1679         *addr += dbg->de_debug_frame_eh_gnu.dss_addr + distance;
1680     }
1681     return DW_DLV_OK;
1682 }
1683 
1684 /*  All augmentation string checking done here now.
1685 
1686     For .eh_frame, gcc from 3.3 uses the z style, earlier used
1687     only "eh" as augmentation.  We don't yet handle
1688     decoding .eh_frame with the z style extensions like L P.
1689     gnu_aug_encodings() does handle L P.
1690 
1691     These are nasty heuristics, but then that's life
1692     as augmentations are implementation specific.  */
1693 /* ARGSUSED */
1694 enum Dwarf_augmentation_type
1695 _dwarf_get_augmentation_type(UNUSEDARG Dwarf_Debug dbg,
1696     Dwarf_Small * augmentation_string,
1697     int is_gcc_eh_frame)
1698 {
1699     enum Dwarf_augmentation_type t = aug_unknown;
1700     char *ag_string = (char *) augmentation_string;
1701 
1702     if (ag_string[0] == 0) {
1703         /*  Empty string. We'll just guess that we know what this means:
1704             standard dwarf2/3 with no implementation-defined fields.  */
1705         t = aug_empty_string;
1706     } else if (strcmp(ag_string, DW_DEBUG_FRAME_AUGMENTER_STRING) == 0) {
1707         /*  The string is "mti v1". Used internally at SGI, probably
1708             never shipped. Replaced by "z". Treat like 'nothing
1709             special'.  */
1710         t = aug_irix_mti_v1;
1711     } else if (ag_string[0] == 'z') {
1712         /*  If it's IRIX cc, z means aug_irix_exception_table. z1 z2
1713             were designed as for IRIX CC, but never implemented */
1714         /*  If it's gcc, z may be any of several things. "z" or z
1715             followed optionally followed by one or more of L R P, each
1716             of which means a value may be present. Should be in eh_frame
1717             only, I think. */
1718         if (is_gcc_eh_frame) {
1719             t = aug_gcc_eh_z;
1720         } else if (ag_string[1] == 0) {
1721             /*  This is the normal IRIX C++ case, where there is an
1722                 offset into a table in each fde. The table being for
1723                 IRIX CC exception handling.  */
1724             /*  DW_CIE_AUGMENTER_STRING_V0 "z" */
1725             t = aug_irix_exception_table;
1726         }                       /* Else unknown. */
1727     } else if (strncmp(ag_string, "eh", 2) == 0) {
1728         /*  gcc .eh_frame augmentation for egcs and gcc 2.x, at least
1729             for x86. */
1730         t = aug_eh;
1731     } else if (strcmp(ag_string, "armcc+") == 0) {
1732         /*  Arm  uses this string to mean a bug in
1733             in Arm compilers was fixed, changing to the standard
1734             calculation of the CFA.  See
1735             http://sourceware.org/ml/gdb-patches/2006-12/msg00249.html
1736             for details. */
1737         t = aug_armcc;
1738     } else if (strcmp(ag_string, "HC") == 0) {
1739         t = aug_metaware;
1740     } else {
1741     }
1742     return t;
1743 }
1744 
1745 /*  Using augmentation, and version
1746     read in the augmentation data for GNU eh.
1747 
1748     Return DW_DLV_OK if we succeeded,
1749     DW_DLV_ERR if we fail.
1750 
1751     On success, update  'size_of_augmentation_data' with
1752     the length of the fields that are part of augmentation (so the
1753     caller can increment frame_ptr appropriately).
1754 
1755     'frame_ptr' points within section.
1756     'section_end' points to end of section area of interest.
1757 
1758 */
1759 /* ARGSUSED */
1760 static int
1761 get_gcc_eh_augmentation(Dwarf_Debug dbg, Dwarf_Small * frame_ptr,
1762     unsigned long *size_of_augmentation_data,
1763     enum Dwarf_augmentation_type augtype,
1764     Dwarf_Small * section_ptr_end,
1765     char *augmentation,
1766     Dwarf_Error *error)
1767 {
1768     char *suffix = 0;
1769     unsigned long augdata_size = 0;
1770 
1771     if (augtype == aug_gcc_eh_z) {
1772         /* Has leading 'z'. */
1773         UNUSEDARG Dwarf_Unsigned val = 0;
1774         Dwarf_Unsigned leb128_length = 0;
1775 
1776         /* Dwarf_Unsigned eh_value = */
1777         DECODE_LEB128_UWORD_LEN_CK(frame_ptr,val,leb128_length,
1778             dbg,error,section_ptr_end);
1779         augdata_size += leb128_length;
1780         suffix = augmentation + 1;
1781     } else {
1782         /*  Prefix is 'eh'.  As in gcc 3.2. No suffix present
1783             apparently. */
1784         suffix = augmentation + 2;
1785     }
1786     /*  FIXME: This could run  too far. */
1787     /* for (; *suffix; ++suffix) if we think we can do something  */
1788     if (*suffix) {
1789         /*  We have no idea what this is as yet.
1790             Some extensions beyond
1791             dwarf exist which we do not yet handle. */
1792         _dwarf_error(dbg, error, DW_DLE_FRAME_AUGMENTATION_UNKNOWN);
1793         return DW_DLV_ERROR;
1794 
1795     }
1796 
1797     *size_of_augmentation_data = augdata_size;
1798     return DW_DLV_OK;
1799 }
1800 
1801 
1802 /* To properly release all spaced used.
1803    Earlier approaches (before July 15, 2005)
1804    letting client do the dealloc directly left
1805    some data allocated.
1806    This is directly called by consumer code.
1807 */
1808 void
1809 dwarf_fde_cie_list_dealloc(Dwarf_Debug dbg,
1810     Dwarf_Cie * cie_data,
1811     Dwarf_Signed cie_element_count,
1812     Dwarf_Fde * fde_data,
1813     Dwarf_Signed fde_element_count)
1814 {
1815     Dwarf_Signed i = 0;
1816 
1817     for (i = 0; i < cie_element_count; ++i) {
1818         Dwarf_Frame frame = cie_data[i]->ci_initial_table;
1819 
1820         if (frame) {
1821             dwarf_dealloc(dbg, frame, DW_DLA_FRAME);
1822         }
1823         dwarf_dealloc(dbg, cie_data[i], DW_DLA_CIE);
1824     }
1825     for (i = 0; i < fde_element_count; ++i) {
1826         dwarf_dealloc(dbg, fde_data[i], DW_DLA_FDE);
1827     }
1828     if (cie_data) {
1829         dwarf_dealloc(dbg, cie_data, DW_DLA_LIST);
1830     }
1831     if (fde_data) {
1832         dwarf_dealloc(dbg, fde_data, DW_DLA_LIST);
1833     }
1834 }
1835