Rev 4383 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4383 | Rev 5963 | ||
---|---|---|---|
Line 1... | Line 1... | ||
1 | /* Subroutines needed for unwinding stack frames for exception handling. */ |
1 | /* Subroutines needed for unwinding stack frames for exception handling. */ |
2 | /* Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2008, |
- | |
3 | 2009 Free Software Foundation, Inc. |
2 | /* Copyright (C) 1997-2013 Free Software Foundation, Inc. |
4 | Contributed by Jason Merrill |
3 | Contributed by Jason Merrill |
Line 5... | Line 4... | ||
5 | 4 | ||
Line 6... | Line 5... | ||
6 | This file is part of GCC. |
5 | This file is part of GCC. |
Line 62... | Line 61... | ||
62 | { |
61 | { |
63 | static __gthread_once_t once = __GTHREAD_ONCE_INIT; |
62 | static __gthread_once_t once = __GTHREAD_ONCE_INIT; |
64 | __gthread_once (&once, init_object_mutex); |
63 | __gthread_once (&once, init_object_mutex); |
65 | } |
64 | } |
66 | #else |
65 | #else |
- | 66 | /* ??? Several targets include this file with stubbing parts of gthr.h |
|
- | 67 | and expect no locking to be done. */ |
|
67 | #define init_object_mutex_once() |
68 | #define init_object_mutex_once() |
68 | #endif |
69 | #endif |
Line 69... | Line 70... | ||
69 | 70 | ||
Line 225... | Line 226... | ||
225 | /* If .eh_frame is empty, we haven't registered. */ |
226 | /* If .eh_frame is empty, we haven't registered. */ |
226 | if (*(uword *) begin != 0) |
227 | if (*(uword *) begin != 0) |
227 | free (__deregister_frame_info (begin)); |
228 | free (__deregister_frame_info (begin)); |
228 | } |
229 | } |
Line 229... | Line -... | ||
229 | - | ||
230 | 230 | ||
231 | /* Like base_of_encoded_value, but take the base from a struct object |
231 | /* Like base_of_encoded_value, but take the base from a struct object |
Line 232... | Line 232... | ||
232 | instead of an _Unwind_Context. */ |
232 | instead of an _Unwind_Context. */ |
233 | 233 | ||
Line 263... | Line 263... | ||
263 | _Unwind_Ptr dummy; |
263 | _Unwind_Ptr dummy; |
264 | _uleb128_t utmp; |
264 | _uleb128_t utmp; |
265 | _sleb128_t stmp; |
265 | _sleb128_t stmp; |
Line 266... | Line 266... | ||
266 | 266 | ||
- | 267 | aug = cie->augmentation; |
|
- | 268 | p = aug + strlen ((const char *)aug) + 1; /* Skip the augmentation string. */ |
|
- | 269 | if (__builtin_expect (cie->version >= 4, 0)) |
|
- | 270 | { |
|
- | 271 | if (p[0] != sizeof (void *) || p[1] != 0) |
|
- | 272 | return DW_EH_PE_omit; /* We are not prepared to handle unexpected |
|
- | 273 | address sizes or segment selectors. */ |
|
- | 274 | p += 2; /* Skip address size and segment size. */ |
|
- | 275 | } |
|
267 | aug = cie->augmentation; |
276 | |
268 | if (aug[0] != 'z') |
277 | if (aug[0] != 'z') |
Line 269... | Line -... | ||
269 | return DW_EH_PE_absptr; |
- | |
270 | 278 | return DW_EH_PE_absptr; |
|
271 | p = aug + strlen ((const char *)aug) + 1; /* Skip the augmentation string. */ |
279 | |
272 | p = read_uleb128 (p, &utmp); /* Skip code alignment. */ |
280 | p = read_uleb128 (p, &utmp); /* Skip code alignment. */ |
273 | p = read_sleb128 (p, &stmp); /* Skip data alignment. */ |
281 | p = read_sleb128 (p, &stmp); /* Skip data alignment. */ |
274 | if (cie->version == 1) /* Skip return address column. */ |
282 | if (cie->version == 1) /* Skip return address column. */ |
Line 612... | Line 620... | ||
612 | this_cie = get_cie (this_fde); |
620 | this_cie = get_cie (this_fde); |
613 | if (this_cie != last_cie) |
621 | if (this_cie != last_cie) |
614 | { |
622 | { |
615 | last_cie = this_cie; |
623 | last_cie = this_cie; |
616 | encoding = get_cie_encoding (this_cie); |
624 | encoding = get_cie_encoding (this_cie); |
- | 625 | if (encoding == DW_EH_PE_omit) |
|
- | 626 | return -1; |
|
617 | base = base_from_object (encoding, ob); |
627 | base = base_from_object (encoding, ob); |
618 | if (ob->s.b.encoding == DW_EH_PE_omit) |
628 | if (ob->s.b.encoding == DW_EH_PE_omit) |
619 | ob->s.b.encoding = encoding; |
629 | ob->s.b.encoding = encoding; |
620 | else if (ob->s.b.encoding != encoding) |
630 | else if (ob->s.b.encoding != encoding) |
621 | ob->s.b.mixed_encoding = 1; |
631 | ob->s.b.mixed_encoding = 1; |
Line 721... | Line 731... | ||
721 | { |
731 | { |
722 | if (ob->s.b.from_array) |
732 | if (ob->s.b.from_array) |
723 | { |
733 | { |
724 | fde **p = ob->u.array; |
734 | fde **p = ob->u.array; |
725 | for (count = 0; *p; ++p) |
735 | for (count = 0; *p; ++p) |
- | 736 | { |
|
726 | count += classify_object_over_fdes (ob, *p); |
737 | size_t cur_count = classify_object_over_fdes (ob, *p); |
- | 738 | if (cur_count == (size_t) -1) |
|
- | 739 | goto unhandled_fdes; |
|
- | 740 | count += cur_count; |
|
- | 741 | } |
|
727 | } |
742 | } |
728 | else |
743 | else |
- | 744 | { |
|
729 | count = classify_object_over_fdes (ob, ob->u.single); |
745 | count = classify_object_over_fdes (ob, ob->u.single); |
- | 746 | if (count == (size_t) -1) |
|
- | 747 | { |
|
- | 748 | static const fde terminator; |
|
- | 749 | unhandled_fdes: |
|
- | 750 | ob->s.i = 0; |
|
- | 751 | ob->s.b.encoding = DW_EH_PE_omit; |
|
- | 752 | ob->u.single = &terminator; |
|
- | 753 | return; |
|
- | 754 | } |
|
- | 755 | } |
|
Line 730... | Line 756... | ||
730 | 756 | ||
731 | /* The count field we have in the main struct object is somewhat |
757 | /* The count field we have in the main struct object is somewhat |
732 | limited, but should suffice for virtually all cases. If the |
758 | limited, but should suffice for virtually all cases. If the |
733 | counted value doesn't fit, re-write a zero. The worst that |
759 | counted value doesn't fit, re-write a zero. The worst that |