1 /*
2 * Copyright (c) 1997, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
2170 // According to Windows API documentation, an illegal instruction sequence should generate
2171 // the 0xC000001C exception code. However, real world experience shows that occasionnaly
2172 // the execution of an illegal instruction can generate the exception code 0xC000001E. This
2173 // seems to be an undocumented feature of Win NT 4.0 (and probably other Windows systems).
2174
2175 #define EXCEPTION_ILLEGAL_INSTRUCTION_2 0xC000001E
2176
2177 // From "Execution Protection in the Windows Operating System" draft 0.35
2178 // Once a system header becomes available, the "real" define should be
2179 // included or copied here.
2180 #define EXCEPTION_INFO_EXEC_VIOLATION 0x08
2181
2182 // Handle NAT Bit consumption on IA64.
2183 #ifdef _M_IA64
2184 #define EXCEPTION_REG_NAT_CONSUMPTION STATUS_REG_NAT_CONSUMPTION
2185 #endif
2186
2187 // Windows Vista/2008 heap corruption check
2188 #define EXCEPTION_HEAP_CORRUPTION 0xC0000374
2189
2190 #define def_excpt(val) #val, val
2191
2192 struct siglabel {
2193 char *name;
2194 int number;
2195 };
2196
2197 // All Visual C++ exceptions thrown from code generated by the Microsoft Visual
2198 // C++ compiler contain this error code. Because this is a compiler-generated
2199 // error, the code is not listed in the Win32 API header files.
2200 // The code is actually a cryptic mnemonic device, with the initial "E"
2201 // standing for "exception" and the final 3 bytes (0x6D7363) representing the
2202 // ASCII values of "msc".
2203
2204 #define EXCEPTION_UNCAUGHT_CXX_EXCEPTION 0xE06D7363
2205
2206
2207 struct siglabel exceptlabels[] = {
2208 def_excpt(EXCEPTION_ACCESS_VIOLATION),
2209 def_excpt(EXCEPTION_DATATYPE_MISALIGNMENT),
2210 def_excpt(EXCEPTION_BREAKPOINT),
2211 def_excpt(EXCEPTION_SINGLE_STEP),
2212 def_excpt(EXCEPTION_ARRAY_BOUNDS_EXCEEDED),
2213 def_excpt(EXCEPTION_FLT_DENORMAL_OPERAND),
2214 def_excpt(EXCEPTION_FLT_DIVIDE_BY_ZERO),
2215 def_excpt(EXCEPTION_FLT_INEXACT_RESULT),
2216 def_excpt(EXCEPTION_FLT_INVALID_OPERATION),
2217 def_excpt(EXCEPTION_FLT_OVERFLOW),
2218 def_excpt(EXCEPTION_FLT_STACK_CHECK),
2219 def_excpt(EXCEPTION_FLT_UNDERFLOW),
2220 def_excpt(EXCEPTION_INT_DIVIDE_BY_ZERO),
2221 def_excpt(EXCEPTION_INT_OVERFLOW),
2222 def_excpt(EXCEPTION_PRIV_INSTRUCTION),
2223 def_excpt(EXCEPTION_IN_PAGE_ERROR),
2224 def_excpt(EXCEPTION_ILLEGAL_INSTRUCTION),
2225 def_excpt(EXCEPTION_ILLEGAL_INSTRUCTION_2),
2226 def_excpt(EXCEPTION_NONCONTINUABLE_EXCEPTION),
2227 def_excpt(EXCEPTION_STACK_OVERFLOW),
2228 def_excpt(EXCEPTION_INVALID_DISPOSITION),
2229 def_excpt(EXCEPTION_GUARD_PAGE),
2230 def_excpt(EXCEPTION_INVALID_HANDLE),
2231 def_excpt(EXCEPTION_UNCAUGHT_CXX_EXCEPTION),
2232 def_excpt(EXCEPTION_HEAP_CORRUPTION),
2233 #ifdef _M_IA64
2234 def_excpt(EXCEPTION_REG_NAT_CONSUMPTION),
2235 #endif
2236 NULL, 0
2237 };
2238
2239 const char* os::exception_name(int exception_code, char *buf, size_t size) {
2240 for (int i = 0; exceptlabels[i].name != NULL; i++) {
2241 if (exceptlabels[i].number == exception_code) {
2242 jio_snprintf(buf, size, "%s", exceptlabels[i].name);
2243 return buf;
2244 }
2245 }
2246
2247 return NULL;
2248 }
2249
2250 //-----------------------------------------------------------------------------
2251 LONG Handle_IDiv_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) {
2252 // handle exception caused by idiv; should only happen for -MinInt/-1
2253 // (division by zero is handled explicitly)
2254 #ifdef _M_IA64
2255 assert(0, "Fix Handle_IDiv_Exception");
2256 #else
2257 #ifdef _M_AMD64
2258 PCONTEXT ctx = exceptionInfo->ContextRecord;
2259 address pc = (address)ctx->Rip;
2260 assert(pc[0] == 0xF7, "not an idiv opcode");
2261 assert((pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands");
|
1 /*
2 * Copyright (c) 1997, 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 *
2170 // According to Windows API documentation, an illegal instruction sequence should generate
2171 // the 0xC000001C exception code. However, real world experience shows that occasionnaly
2172 // the execution of an illegal instruction can generate the exception code 0xC000001E. This
2173 // seems to be an undocumented feature of Win NT 4.0 (and probably other Windows systems).
2174
2175 #define EXCEPTION_ILLEGAL_INSTRUCTION_2 0xC000001E
2176
2177 // From "Execution Protection in the Windows Operating System" draft 0.35
2178 // Once a system header becomes available, the "real" define should be
2179 // included or copied here.
2180 #define EXCEPTION_INFO_EXEC_VIOLATION 0x08
2181
2182 // Handle NAT Bit consumption on IA64.
2183 #ifdef _M_IA64
2184 #define EXCEPTION_REG_NAT_CONSUMPTION STATUS_REG_NAT_CONSUMPTION
2185 #endif
2186
2187 // Windows Vista/2008 heap corruption check
2188 #define EXCEPTION_HEAP_CORRUPTION 0xC0000374
2189
2190 // All Visual C++ exceptions thrown from code generated by the Microsoft Visual
2191 // C++ compiler contain this error code. Because this is a compiler-generated
2192 // error, the code is not listed in the Win32 API header files.
2193 // The code is actually a cryptic mnemonic device, with the initial "E"
2194 // standing for "exception" and the final 3 bytes (0x6D7363) representing the
2195 // ASCII values of "msc".
2196
2197 #define EXCEPTION_UNCAUGHT_CXX_EXCEPTION 0xE06D7363
2198
2199 #define def_excpt(val) { #val, (val) }
2200
2201 static const struct { char* name; uint number; } exceptlabels[] = {
2202 def_excpt(EXCEPTION_ACCESS_VIOLATION),
2203 def_excpt(EXCEPTION_DATATYPE_MISALIGNMENT),
2204 def_excpt(EXCEPTION_BREAKPOINT),
2205 def_excpt(EXCEPTION_SINGLE_STEP),
2206 def_excpt(EXCEPTION_ARRAY_BOUNDS_EXCEEDED),
2207 def_excpt(EXCEPTION_FLT_DENORMAL_OPERAND),
2208 def_excpt(EXCEPTION_FLT_DIVIDE_BY_ZERO),
2209 def_excpt(EXCEPTION_FLT_INEXACT_RESULT),
2210 def_excpt(EXCEPTION_FLT_INVALID_OPERATION),
2211 def_excpt(EXCEPTION_FLT_OVERFLOW),
2212 def_excpt(EXCEPTION_FLT_STACK_CHECK),
2213 def_excpt(EXCEPTION_FLT_UNDERFLOW),
2214 def_excpt(EXCEPTION_INT_DIVIDE_BY_ZERO),
2215 def_excpt(EXCEPTION_INT_OVERFLOW),
2216 def_excpt(EXCEPTION_PRIV_INSTRUCTION),
2217 def_excpt(EXCEPTION_IN_PAGE_ERROR),
2218 def_excpt(EXCEPTION_ILLEGAL_INSTRUCTION),
2219 def_excpt(EXCEPTION_ILLEGAL_INSTRUCTION_2),
2220 def_excpt(EXCEPTION_NONCONTINUABLE_EXCEPTION),
2221 def_excpt(EXCEPTION_STACK_OVERFLOW),
2222 def_excpt(EXCEPTION_INVALID_DISPOSITION),
2223 def_excpt(EXCEPTION_GUARD_PAGE),
2224 def_excpt(EXCEPTION_INVALID_HANDLE),
2225 def_excpt(EXCEPTION_UNCAUGHT_CXX_EXCEPTION),
2226 def_excpt(EXCEPTION_HEAP_CORRUPTION)
2227 #ifdef _M_IA64
2228 , def_excpt(EXCEPTION_REG_NAT_CONSUMPTION),
2229 #endif
2230 };
2231
2232 const char* os::exception_name(int exception_code, char *buf, size_t size) {
2233 uint code = static_cast<uint>(exception_code);
2234 for (uint i = 0; i < ARRAY_SIZE(exceptlabels); ++i) {
2235 if (exceptlabels[i].number == code) {
2236 jio_snprintf(buf, size, "%s", exceptlabels[i].name);
2237 return buf;
2238 }
2239 }
2240
2241 return NULL;
2242 }
2243
2244 //-----------------------------------------------------------------------------
2245 LONG Handle_IDiv_Exception(struct _EXCEPTION_POINTERS* exceptionInfo) {
2246 // handle exception caused by idiv; should only happen for -MinInt/-1
2247 // (division by zero is handled explicitly)
2248 #ifdef _M_IA64
2249 assert(0, "Fix Handle_IDiv_Exception");
2250 #else
2251 #ifdef _M_AMD64
2252 PCONTEXT ctx = exceptionInfo->ContextRecord;
2253 address pc = (address)ctx->Rip;
2254 assert(pc[0] == 0xF7, "not an idiv opcode");
2255 assert((pc[1] & ~0x7) == 0xF8, "cannot handle non-register operands");
|