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