1201 |
|
} |
1202 |
|
|
1203 |
|
#ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION |
1204 |
+ |
#ifdef __GNUC__ |
1205 |
+ |
// Code range where we expect the fault to come from |
1206 |
+ |
static void *b_region, *e_region; |
1207 |
+ |
#endif |
1208 |
+ |
|
1209 |
|
static sigsegv_return_t sigsegv_insn_handler(sigsegv_address_t fault_address, sigsegv_address_t instruction_address) |
1210 |
|
{ |
1211 |
< |
if (((unsigned long)fault_address - (unsigned long)page) < page_size) |
1211 |
> |
if (((unsigned long)fault_address - (unsigned long)page) < page_size) { |
1212 |
> |
#ifdef __GNUC__ |
1213 |
> |
// Make sure reported fault instruction address falls into |
1214 |
> |
// expected code range |
1215 |
> |
if (instruction_address != SIGSEGV_INVALID_PC |
1216 |
> |
&& ((instruction_address < (sigsegv_address_t)b_region) || |
1217 |
> |
(instruction_address >= (sigsegv_address_t)e_region))) |
1218 |
> |
return SIGSEGV_RETURN_FAILURE; |
1219 |
> |
#endif |
1220 |
|
return SIGSEGV_RETURN_SKIP_INSTRUCTION; |
1221 |
+ |
} |
1222 |
+ |
|
1223 |
|
return SIGSEGV_RETURN_FAILURE; |
1224 |
|
} |
1225 |
|
#endif |
1266 |
|
return 1; \ |
1267 |
|
} while (0) |
1268 |
|
|
1269 |
+ |
#ifdef __GNUC__ |
1270 |
+ |
b_region = &&L_b_region; |
1271 |
+ |
e_region = &&L_e_region; |
1272 |
+ |
#endif |
1273 |
+ |
L_b_region: |
1274 |
|
TEST_SKIP_INSTRUCTION(unsigned char); |
1275 |
|
TEST_SKIP_INSTRUCTION(unsigned short); |
1276 |
|
TEST_SKIP_INSTRUCTION(unsigned int); |
1277 |
+ |
L_e_region: |
1278 |
|
#endif |
1279 |
|
|
1280 |
|
vm_exit(); |