OpenWrt – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | From 1dc865b8bbb3911abc8ce53c7ae8a59dc90f6fc3 Mon Sep 17 00:00:00 2001 |
2 | From: Ivan Kold <pixus.ru@gmail.com> |
||
3 | Date: Thu, 3 Mar 2016 12:56:30 -0800 |
||
4 | Subject: [PATCH] Fix throw statement causing memory corruption |
||
5 | |||
6 | The __cxxabiv1::__cxa_throw in the GCC's libsupc++ expects |
||
7 | sizeof(__cxa_refcounted_exception) bytes be allocated before |
||
8 | exception object. |
||
9 | uClibc++ allocates only sizeof(__cxa_exception) before an |
||
10 | exception object. |
||
11 | The __cxxabiv1::__cxa_throw writes in memory before allocated: |
||
12 | // gcc-5.2.0/libstdc++-v3/libsupc++/eh_throw.cc:69 |
||
13 | __cxa_refcounted_exception *header |
||
14 | = __get_refcounted_exception_header_from_obj (obj); |
||
15 | header->referenceCount = 1; |
||
16 | |||
17 | Signed-off-by: Ivan Kold <pixus.ru@gmail.com> |
||
18 | --- |
||
19 | include/unwind-cxx.h | 34 +++++++++++++++++++++++++++++++++- |
||
20 | src/eh_alloc.cpp | 8 ++++---- |
||
21 | 2 files changed, 37 insertions(+), 5 deletions(-) |
||
22 | |||
23 | --- a/include/unwind-cxx.h |
||
24 | +++ b/include/unwind-cxx.h |
||
25 | @@ -1,5 +1,5 @@ |
||
26 | // -*- C++ -*- Exception handling and frame unwind runtime interface routines. |
||
27 | -// Copyright (C) 2001 Free Software Foundation, Inc. |
||
28 | +// Copyright (C) 2001-2015 Free Software Foundation, Inc. |
||
29 | // |
||
30 | // This file is part of GCC. |
||
31 | // |
||
32 | @@ -13,6 +13,10 @@ |
||
33 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||
34 | // GNU General Public License for more details. |
||
35 | // |
||
36 | +// Under Section 7 of GPL version 3, you are granted additional |
||
37 | +// permissions described in the GCC Runtime Library Exception, version |
||
38 | +// 3.1, as published by the Free Software Foundation. |
||
39 | +// |
||
40 | // You should have received a copy of the GNU General Public License |
||
41 | // along with GCC; see the file COPYING. If not, write to |
||
42 | // the Free Software Foundation, 59 Temple Place - Suite 330, |
||
43 | @@ -40,6 +44,12 @@ |
||
44 | #include <cstddef> |
||
45 | #include "unwind.h" |
||
46 | |||
47 | +// Original unwind-cxx.h also includes bits/atomic_word.h which is CPU-specific, |
||
48 | +// but always defines _Atomic_word as typedef int . |
||
49 | +// Only thing that differs is memory-barrier macroses. |
||
50 | +typedef int _Atomic_word; |
||
51 | + |
||
52 | + |
||
53 | #pragma GCC visibility push(default) |
||
54 | |||
55 | namespace __cxxabiv1 |
||
56 | @@ -79,6 +89,13 @@ struct __cxa_exception |
||
57 | _Unwind_Exception unwindHeader; |
||
58 | }; |
||
59 | |||
60 | +struct __cxa_refcounted_exception |
||
61 | +{ |
||
62 | + // Manage this header. |
||
63 | + _Atomic_word referenceCount; |
||
64 | + // __cxa_exception must be last, and no padding can be after it. |
||
65 | + __cxa_exception exc; |
||
66 | +}; |
||
67 | |||
68 | // A dependent C++ exception object consists of a header, which is a wrapper |
||
69 | // around an unwind object header with additional C++ specific information, |
||
70 | @@ -210,6 +227,21 @@ __get_exception_header_from_ue (_Unwind_ |
||
71 | return reinterpret_cast<__cxa_exception *>(exc + 1) - 1; |
||
72 | } |
||
73 | |||
74 | +// Acquire the C++ refcounted exception header from the C++ object. |
||
75 | +static inline __cxa_refcounted_exception * |
||
76 | +__get_refcounted_exception_header_from_obj (void *ptr) |
||
77 | +{ |
||
78 | + return reinterpret_cast<__cxa_refcounted_exception *>(ptr) - 1; |
||
79 | +} |
||
80 | + |
||
81 | +// Acquire the C++ refcounted exception header from the generic exception |
||
82 | +// header. |
||
83 | +static inline __cxa_refcounted_exception * |
||
84 | +__get_refcounted_exception_header_from_ue (_Unwind_Exception *exc) |
||
85 | +{ |
||
86 | + return reinterpret_cast<__cxa_refcounted_exception *>(exc + 1) - 1; |
||
87 | +} |
||
88 | + |
||
89 | } /* namespace __cxxabiv1 */ |
||
90 | |||
91 | #pragma GCC visibility pop |
||
92 | --- a/src/eh_alloc.cpp |
||
93 | +++ b/src/eh_alloc.cpp |
||
94 | @@ -30,16 +30,16 @@ extern "C" void * __cxa_allocate_excepti |
||
95 | void *retval; |
||
96 | //The sizeof crap is required by Itanium ABI because we need to provide space for |
||
97 | //accounting information which is implementaion (gcc) specified |
||
98 | - retval = malloc (thrown_size + sizeof(__cxa_exception)); |
||
99 | + retval = malloc (thrown_size + sizeof(__cxa_refcounted_exception)); |
||
100 | if (0 == retval){ |
||
101 | std::terminate(); |
||
102 | } |
||
103 | - memset (retval, 0, sizeof(__cxa_exception)); |
||
104 | - return (void *)((unsigned char *)retval + sizeof(__cxa_exception)); |
||
105 | + memset (retval, 0, sizeof(__cxa_refcounted_exception)); |
||
106 | + return (void *)((unsigned char *)retval + sizeof(__cxa_refcounted_exception)); |
||
107 | } |
||
108 | |||
109 | extern "C" void __cxa_free_exception(void *vptr) throw(){ |
||
110 | - free( (char *)(vptr) - sizeof(__cxa_exception) ); |
||
111 | + free( (char *)(vptr) - sizeof(__cxa_refcounted_exception) ); |
||
112 | } |
||
113 | |||
114 |