Line | Count | Source |
1 | | /* except.cpp -- |
2 | | |
3 | | This file is part of the UPX executable compressor. |
4 | | |
5 | | Copyright (C) Markus Franz Xaver Johannes Oberhumer |
6 | | Copyright (C) Laszlo Molnar |
7 | | All Rights Reserved. |
8 | | |
9 | | UPX and the UCL library are free software; you can redistribute them |
10 | | and/or modify them under the terms of the GNU General Public License as |
11 | | published by the Free Software Foundation; either version 2 of |
12 | | the License, or (at your option) any later version. |
13 | | |
14 | | This program is distributed in the hope that it will be useful, |
15 | | but WITHOUT ANY WARRANTY; without even the implied warranty of |
16 | | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
17 | | GNU General Public License for more details. |
18 | | |
19 | | You should have received a copy of the GNU General Public License |
20 | | along with this program; see the file COPYING. |
21 | | If not, write to the Free Software Foundation, Inc., |
22 | | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
23 | | |
24 | | Markus F.X.J. Oberhumer Laszlo Molnar |
25 | | <markus@oberhumer.com> <ezerotven+github@gmail.com> |
26 | | */ |
27 | | |
28 | | #include "conf.h" |
29 | | |
30 | | /************************************************************************* |
31 | | // |
32 | | **************************************************************************/ |
33 | | |
34 | | /*static*/ Throwable::Stats Throwable::stats; |
35 | | |
36 | 4.54M | Throwable::Throwable(const char *m, int e, bool w) noexcept : super(), |
37 | 4.54M | msg(nullptr), |
38 | 4.54M | err(e), |
39 | 4.54M | is_warning(w) { |
40 | 4.54M | if (m != nullptr) { |
41 | 4.54M | msg = ::strdup(m); |
42 | 4.54M | assert_noexcept(msg != nullptr); |
43 | 4.54M | } |
44 | 4.54M | NO_fprintf(stderr, "construct exception: %zu %zu %s\n", size_t(stats.counter_current), |
45 | 4.54M | size_t(stats.counter_total), (const char *) msg); |
46 | 4.54M | stats.counter_current += 1; |
47 | 4.54M | stats.counter_total += 1; |
48 | 4.54M | } |
49 | | |
50 | 0 | Throwable::Throwable(const Throwable &other) noexcept : super(other), |
51 | 0 | msg(nullptr), |
52 | 0 | err(other.err), |
53 | 0 | is_warning(other.is_warning) { |
54 | 0 | if (other.msg != nullptr) { |
55 | 0 | msg = ::strdup(other.msg); |
56 | 0 | assert_noexcept(msg != nullptr); |
57 | 0 | } |
58 | 0 | NO_fprintf(stderr, "copy construct exception: %zu %zu %s\n", size_t(stats.counter_current), |
59 | 0 | size_t(stats.counter_total), (const char *) msg); |
60 | 0 | stats.counter_current += 1; |
61 | 0 | stats.counter_total += 1; |
62 | 0 | } |
63 | | |
64 | 4.54M | Throwable::~Throwable() noexcept { |
65 | 4.54M | stats.counter_current -= 1; |
66 | 4.54M | NO_fprintf(stderr, "destruct exception: %zu %zu %s\n", size_t(stats.counter_current), |
67 | 4.54M | size_t(stats.counter_total), (const char *) msg); |
68 | 4.54M | upx::owner_free(msg); |
69 | 4.54M | } |
70 | | |
71 | | /************************************************************************* |
72 | | // compression |
73 | | **************************************************************************/ |
74 | | |
75 | 4.47M | void throwCantPack(const char *msg) { |
76 | | // UGLY, but makes things easier |
77 | 4.47M | if (opt->cmd == CMD_NONE) |
78 | 298 | throw CantPackException(msg); |
79 | 4.47M | else if (opt->cmd == CMD_COMPRESS) |
80 | 0 | throw CantPackException(msg); |
81 | 4.47M | else if (opt->cmd == CMD_FILEINFO) |
82 | 0 | throw CantPackException(msg); |
83 | 4.47M | else |
84 | 4.47M | throw CantUnpackException(msg); |
85 | 4.47M | } |
86 | | |
87 | 0 | void throwCantPackExact() { throwCantPack("option '--exact' does not work with this file"); } |
88 | | |
89 | 0 | void throwFilterException() { throwCantPack("filter problem"); } |
90 | | |
91 | 80 | void throwUnknownExecutableFormat(const char *msg, bool warn) { |
92 | 80 | throw UnknownExecutableFormatException(msg, warn); |
93 | 80 | } |
94 | | |
95 | 0 | void throwNotCompressible(const char *msg) { throw NotCompressibleException(msg); } |
96 | | |
97 | 0 | void throwAlreadyPacked(const char *msg) { throw AlreadyPackedException(msg); } |
98 | | |
99 | 0 | void throwAlreadyPackedByUPX(const char *msg) { |
100 | 0 | if (msg == nullptr) |
101 | 0 | msg = "already packed by UPX"; |
102 | 0 | throwAlreadyPacked(msg); |
103 | 0 | } |
104 | | |
105 | | /************************************************************************* |
106 | | // decompression |
107 | | **************************************************************************/ |
108 | | |
109 | 5.28k | void throwCantUnpack(const char *msg) { |
110 | | // UGLY, but makes things easier |
111 | 5.28k | throwCantPack(msg); |
112 | 5.28k | } |
113 | | |
114 | 2.62k | void throwNotPacked(const char *msg) { |
115 | 2.62k | if (msg == nullptr) |
116 | 2.62k | msg = "not packed by UPX"; |
117 | 2.62k | throw NotPackedException(msg); |
118 | 2.62k | } |
119 | | |
120 | 183 | void throwChecksumError() { throw Exception("checksum error"); } |
121 | | |
122 | 3.21k | void throwCompressedDataViolation() { throw Exception("compressed data violation"); } |
123 | | |
124 | | /************************************************************************* |
125 | | // other |
126 | | **************************************************************************/ |
127 | | |
128 | 29.9k | void throwInternalError(const char *msg) { throw InternalError(msg); } |
129 | | |
130 | 0 | void throwBadLoader() { throwInternalError("bad loader"); } |
131 | | |
132 | 0 | void throwOutOfMemoryException(const char *msg) { |
133 | 0 | if (msg == nullptr) |
134 | 0 | msg = "out of memory"; |
135 | 0 | throw OutOfMemoryException(msg); |
136 | 0 | } |
137 | | |
138 | 15.1k | void throwIOException(const char *msg, int e) { throw IOException(msg, e); } |
139 | | |
140 | 16.6k | void throwEOFException(const char *msg, int e) { |
141 | 16.6k | if (msg == nullptr && e == 0) |
142 | 16.6k | msg = "premature end of file"; |
143 | 16.6k | throw EOFException(msg, e); |
144 | 16.6k | } |
145 | | |
146 | | /************************************************************************* |
147 | | // varargs overloads |
148 | | **************************************************************************/ |
149 | | |
150 | | template <> |
151 | 16.1k | void throwCantPack(const char *format, ...) { |
152 | 16.1k | char msg[1024]; |
153 | 16.1k | va_list ap; |
154 | 16.1k | va_start(ap, format); |
155 | 16.1k | upx_safe_vsnprintf_noexcept(msg, sizeof(msg), format, ap); |
156 | 16.1k | va_end(ap); |
157 | 16.1k | throwCantPack(msg); |
158 | 16.1k | } |
159 | | |
160 | | template <> |
161 | 1.07k | void throwCantUnpack(const char *format, ...) { |
162 | 1.07k | char msg[1024]; |
163 | 1.07k | va_list ap; |
164 | 1.07k | va_start(ap, format); |
165 | 1.07k | upx_safe_vsnprintf_noexcept(msg, sizeof(msg), format, ap); |
166 | 1.07k | va_end(ap); |
167 | 1.07k | throwCantUnpack(msg); |
168 | 1.07k | } |
169 | | |
170 | | template <> |
171 | 7 | void throwInternalError(const char *format, ...) { |
172 | 7 | char msg[1024]; |
173 | 7 | va_list ap; |
174 | 7 | va_start(ap, format); |
175 | 7 | upx_safe_vsnprintf_noexcept(msg, sizeof(msg), format, ap); |
176 | 7 | va_end(ap); |
177 | 7 | throwInternalError(msg); |
178 | 7 | } |
179 | | |
180 | | /************************************************************************* |
181 | | // util |
182 | | **************************************************************************/ |
183 | | |
184 | 0 | void assertFailed(const char *expr, const char *file, int line, const char *func) noexcept { |
185 | 0 | fflush(stdout); |
186 | 0 | fprintf(stderr, "Assertion failed: %s (%s: %s: %d)\n", expr, file, func, line); |
187 | 0 | std::terminate(); |
188 | 0 | } |
189 | | |
190 | 2.63M | void assertFailed(int e, const char *expr, const char *file, int line, const char *func) noexcept { |
191 | 2.63M | if very_unlikely (!e) |
192 | 0 | assertFailed(expr, file, line, func); |
193 | 2.63M | } |
194 | | |
195 | 63 | void throwAssertFailed(const char *expr, const char *file, int line, const char *func) may_throw { |
196 | 63 | if (opt->debug.debug_level >= 1) { |
197 | 0 | throwCantPack("corrupted file; details: %s (%s: %s: %d)", expr, file, func, line); |
198 | 63 | } else { |
199 | 63 | throwCantPack("corrupted file; try '--debug' for more details"); |
200 | 63 | } |
201 | 63 | } |
202 | | |
203 | 14.9k | const char *prettyExceptionName(const char *n) noexcept { |
204 | 14.9k | if (n == nullptr) |
205 | 0 | return "(null)"; |
206 | 41.4k | while (*n) { |
207 | 41.4k | if (*n >= '0' && *n <= '9') // Linux ABI |
208 | 26.4k | n++; |
209 | 14.9k | else if (*n == ' ') |
210 | 0 | n++; |
211 | 14.9k | else if (strncmp(n, "class ", 6) == 0) // Visual C++ (MSVC) |
212 | 0 | n += 6; |
213 | 14.9k | else |
214 | 14.9k | break; |
215 | 41.4k | } |
216 | 14.9k | return n; |
217 | 14.9k | } |
218 | | |
219 | | /* vim:set ts=4 sw=4 et: */ |