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