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