221 |
|
#define SIGSEGV_FAULT_HANDLER_ARGLIST_1 siginfo_t *sip, void *scp |
222 |
|
#define SIGSEGV_FAULT_HANDLER_ARGS sip, scp |
223 |
|
#define SIGSEGV_FAULT_ADDRESS sip->si_addr |
224 |
+ |
#if defined(__sun__) |
225 |
+ |
#if (defined(sparc) || defined(__sparc__)) |
226 |
+ |
#include <sys/ucontext.h> |
227 |
+ |
#define SIGSEGV_CONTEXT_REGS (((ucontext_t *)scp)->uc_mcontext.gregs) |
228 |
+ |
#define SIGSEGV_FAULT_INSTRUCTION SIGSEGV_CONTEXT_REGS[REG_PC] |
229 |
+ |
#endif |
230 |
+ |
#endif |
231 |
|
#if defined(__NetBSD__) || defined(__FreeBSD__) |
232 |
|
#if (defined(i386) || defined(__i386__)) |
233 |
|
#define SIGSEGV_FAULT_INSTRUCTION (((struct sigcontext *)scp)->sc_eip) |
1199 |
|
#include <sys/mman.h> |
1200 |
|
#include "vm_alloc.h" |
1201 |
|
|
1202 |
+ |
const int REF_INDEX = 123; |
1203 |
+ |
const int REF_VALUE = 45; |
1204 |
+ |
|
1205 |
|
static int page_size; |
1206 |
|
static volatile char * page = 0; |
1207 |
|
static volatile int handler_called = 0; |
1208 |
|
|
1209 |
+ |
#ifdef __GNUC__ |
1210 |
+ |
// Code range where we expect the fault to come from |
1211 |
+ |
static void *b_region, *e_region; |
1212 |
+ |
#endif |
1213 |
+ |
|
1214 |
|
static sigsegv_return_t sigsegv_test_handler(sigsegv_address_t fault_address, sigsegv_address_t instruction_address) |
1215 |
|
{ |
1216 |
|
handler_called++; |
1217 |
< |
if ((fault_address - 123) != page) |
1217 |
> |
if ((fault_address - REF_INDEX) != page) |
1218 |
|
exit(10); |
1219 |
< |
if (vm_protect((char *)((unsigned long)fault_address & -page_size), page_size, VM_PAGE_READ | VM_PAGE_WRITE) != 0) |
1219 |
> |
#ifdef __GNUC__ |
1220 |
> |
// Make sure reported fault instruction address falls into |
1221 |
> |
// expected code range |
1222 |
> |
if (instruction_address != SIGSEGV_INVALID_PC |
1223 |
> |
&& ((instruction_address < (sigsegv_address_t)b_region) || |
1224 |
> |
(instruction_address >= (sigsegv_address_t)e_region))) |
1225 |
|
exit(11); |
1226 |
+ |
#endif |
1227 |
+ |
if (vm_protect((char *)((unsigned long)fault_address & -page_size), page_size, VM_PAGE_READ | VM_PAGE_WRITE) != 0) |
1228 |
+ |
exit(12); |
1229 |
|
return SIGSEGV_RETURN_SUCCESS; |
1230 |
|
} |
1231 |
|
|
1232 |
|
#ifdef HAVE_SIGSEGV_SKIP_INSTRUCTION |
1210 |
– |
#ifdef __GNUC__ |
1211 |
– |
// Code range where we expect the fault to come from |
1212 |
– |
static void *b_region, *e_region; |
1213 |
– |
#endif |
1214 |
– |
|
1233 |
|
static sigsegv_return_t sigsegv_insn_handler(sigsegv_address_t fault_address, sigsegv_address_t instruction_address) |
1234 |
|
{ |
1235 |
|
if (((unsigned long)fault_address - (unsigned long)page) < page_size) { |
1257 |
|
if ((page = (char *)vm_acquire(page_size)) == VM_MAP_FAILED) |
1258 |
|
return 2; |
1259 |
|
|
1260 |
+ |
memset((void *)page, 0, page_size); |
1261 |
|
if (vm_protect((char *)page, page_size, VM_PAGE_READ) < 0) |
1262 |
|
return 3; |
1263 |
|
|
1264 |
|
if (!sigsegv_install_handler(sigsegv_test_handler)) |
1265 |
|
return 4; |
1266 |
|
|
1267 |
< |
page[123] = 45; |
1268 |
< |
page[123] = 45; |
1269 |
< |
|
1267 |
> |
#ifdef __GNUC__ |
1268 |
> |
b_region = &&L_b_region1; |
1269 |
> |
e_region = &&L_e_region1; |
1270 |
> |
#endif |
1271 |
> |
L_b_region1: |
1272 |
> |
page[REF_INDEX] = REF_VALUE; |
1273 |
> |
if (page[REF_INDEX] != REF_VALUE) |
1274 |
> |
exit(20); |
1275 |
> |
page[REF_INDEX] = REF_VALUE; |
1276 |
> |
L_e_region1: |
1277 |
> |
|
1278 |
|
if (handler_called != 1) |
1279 |
|
return 5; |
1280 |
|
|
1300 |
|
} while (0) |
1301 |
|
|
1302 |
|
#ifdef __GNUC__ |
1303 |
< |
b_region = &&L_b_region; |
1304 |
< |
e_region = &&L_e_region; |
1303 |
> |
b_region = &&L_b_region2; |
1304 |
> |
e_region = &&L_e_region2; |
1305 |
|
#endif |
1306 |
< |
L_b_region: |
1306 |
> |
L_b_region2: |
1307 |
|
TEST_SKIP_INSTRUCTION(unsigned char); |
1308 |
|
TEST_SKIP_INSTRUCTION(unsigned short); |
1309 |
|
TEST_SKIP_INSTRUCTION(unsigned int); |
1310 |
< |
L_e_region: |
1310 |
> |
L_e_region2: |
1311 |
|
#endif |
1312 |
|
|
1313 |
|
vm_exit(); |
1314 |
|
return 0; |
1315 |
|
} |
1316 |
|
#endif |
1317 |
+ |
|
1318 |
+ |
|
1319 |
+ |
|
1320 |
+ |
|
1321 |
+ |
|
1322 |
+ |
|
1323 |
+ |
|
1324 |
+ |
|
1325 |
+ |
|
1326 |
+ |
|
1327 |
+ |
|
1328 |
+ |
|
1329 |
+ |
|
1330 |
+ |
|
1331 |
+ |
|