1063 |
#endif |
#endif |
1064 |
|
|
1065 |
jmp_buf jmp_env; |
jmp_buf jmp_env; |
|
int dump_eip; |
|
|
int dump_si_addr; |
|
1066 |
int v1; |
int v1; |
1067 |
int tab[2]; |
int tab[2]; |
1068 |
|
|
1072 |
|
|
1073 |
printf("si_signo=%d si_errno=%d si_code=%d", |
printf("si_signo=%d si_errno=%d si_code=%d", |
1074 |
info->si_signo, info->si_errno, info->si_code); |
info->si_signo, info->si_errno, info->si_code); |
1075 |
if (dump_si_addr) { |
printf(" si_addr=0x%08lx", |
1076 |
printf(" si_addr=0x%08lx", |
(unsigned long)info->si_addr); |
|
(unsigned long)info->si_addr); |
|
|
} |
|
1077 |
printf("\n"); |
printf("\n"); |
1078 |
|
|
1079 |
printf("trapno=0x%02x err=0x%08x", |
printf("trapno=0x%02x err=0x%08x", |
1080 |
uc->uc_mcontext.gregs[REG_TRAPNO], |
uc->uc_mcontext.gregs[REG_TRAPNO], |
1081 |
uc->uc_mcontext.gregs[REG_ERR]); |
uc->uc_mcontext.gregs[REG_ERR]); |
1082 |
if (dump_eip) |
printf(" EIP=0x%08x", uc->uc_mcontext.gregs[REG_EIP]); |
|
printf(" EIP=0x%08x", uc->uc_mcontext.gregs[REG_EIP]); |
|
1083 |
printf("\n"); |
printf("\n"); |
1084 |
longjmp(jmp_env, 1); |
longjmp(jmp_env, 1); |
1085 |
} |
} |
1086 |
|
|
1087 |
void test_exceptions(void) |
void test_exceptions(void) |
1088 |
{ |
{ |
1089 |
|
struct modify_ldt_ldt_s ldt; |
1090 |
struct sigaction act; |
struct sigaction act; |
1091 |
volatile int val; |
volatile int val; |
1092 |
|
|
1096 |
sigaction(SIGFPE, &act, NULL); |
sigaction(SIGFPE, &act, NULL); |
1097 |
sigaction(SIGILL, &act, NULL); |
sigaction(SIGILL, &act, NULL); |
1098 |
sigaction(SIGSEGV, &act, NULL); |
sigaction(SIGSEGV, &act, NULL); |
1099 |
|
sigaction(SIGBUS, &act, NULL); |
1100 |
sigaction(SIGTRAP, &act, NULL); |
sigaction(SIGTRAP, &act, NULL); |
1101 |
|
|
1102 |
/* test division by zero reporting */ |
/* test division by zero reporting */ |
1103 |
dump_eip = 0; |
printf("DIVZ exception:\n"); |
|
dump_si_addr = 0; |
|
|
printf("DIVZ exception (currently imprecise):\n"); |
|
1104 |
if (setjmp(jmp_env) == 0) { |
if (setjmp(jmp_env) == 0) { |
1105 |
/* now divide by zero */ |
/* now divide by zero */ |
1106 |
v1 = 0; |
v1 = 0; |
1107 |
v1 = 2 / v1; |
v1 = 2 / v1; |
1108 |
} |
} |
1109 |
|
|
1110 |
dump_si_addr = 1; |
printf("BOUND exception:\n"); |
|
printf("BOUND exception (currently imprecise):\n"); |
|
1111 |
if (setjmp(jmp_env) == 0) { |
if (setjmp(jmp_env) == 0) { |
1112 |
/* bound exception */ |
/* bound exception */ |
1113 |
tab[0] = 1; |
tab[0] = 1; |
1115 |
asm volatile ("bound %0, %1" : : "r" (11), "m" (tab)); |
asm volatile ("bound %0, %1" : : "r" (11), "m" (tab)); |
1116 |
} |
} |
1117 |
|
|
1118 |
|
printf("segment exceptions:\n"); |
1119 |
|
if (setjmp(jmp_env) == 0) { |
1120 |
|
/* load an invalid segment */ |
1121 |
|
asm volatile ("movl %0, %%fs" : : "r" ((0x1234 << 3) | 1)); |
1122 |
|
} |
1123 |
|
if (setjmp(jmp_env) == 0) { |
1124 |
|
/* null data segment is valid */ |
1125 |
|
asm volatile ("movl %0, %%fs" : : "r" (3)); |
1126 |
|
/* null stack segment */ |
1127 |
|
asm volatile ("movl %0, %%ss" : : "r" (3)); |
1128 |
|
} |
1129 |
|
|
1130 |
|
ldt.entry_number = 1; |
1131 |
|
ldt.base_addr = (unsigned long)&seg_data1; |
1132 |
|
ldt.limit = (sizeof(seg_data1) + 0xfff) >> 12; |
1133 |
|
ldt.seg_32bit = 1; |
1134 |
|
ldt.contents = MODIFY_LDT_CONTENTS_DATA; |
1135 |
|
ldt.read_exec_only = 0; |
1136 |
|
ldt.limit_in_pages = 1; |
1137 |
|
ldt.seg_not_present = 1; |
1138 |
|
ldt.useable = 1; |
1139 |
|
modify_ldt(1, &ldt, sizeof(ldt)); /* write ldt entry */ |
1140 |
|
|
1141 |
|
if (setjmp(jmp_env) == 0) { |
1142 |
|
/* segment not present */ |
1143 |
|
asm volatile ("movl %0, %%fs" : : "r" (MK_SEL(1))); |
1144 |
|
} |
1145 |
|
|
1146 |
/* test SEGV reporting */ |
/* test SEGV reporting */ |
1147 |
printf("PF exception (currently imprecise):\n"); |
printf("PF exception:\n"); |
1148 |
if (setjmp(jmp_env) == 0) { |
if (setjmp(jmp_env) == 0) { |
1149 |
|
val = 1; |
1150 |
/* now store in an invalid address */ |
/* now store in an invalid address */ |
1151 |
*(char *)0x1234 = 1; |
*(char *)0x1234 = 1; |
1152 |
} |
} |
1153 |
|
|
1154 |
/* test SEGV reporting */ |
/* test SEGV reporting */ |
1155 |
printf("PF exception (currently imprecise):\n"); |
printf("PF exception:\n"); |
1156 |
if (setjmp(jmp_env) == 0) { |
if (setjmp(jmp_env) == 0) { |
1157 |
|
val = 1; |
1158 |
/* read from an invalid address */ |
/* read from an invalid address */ |
1159 |
v1 = *(char *)0x1234; |
v1 = *(char *)0x1234; |
1160 |
} |
} |
1161 |
|
|
|
printf("segment GPF exception (currently imprecise):\n"); |
|
|
if (setjmp(jmp_env) == 0) { |
|
|
/* load an invalid segment */ |
|
|
asm volatile ("movl %0, %%fs" : : "r" ((0x1234 << 3) | 0)); |
|
|
} |
|
|
|
|
|
dump_eip = 1; |
|
1162 |
/* test illegal instruction reporting */ |
/* test illegal instruction reporting */ |
1163 |
printf("UD2 exception:\n"); |
printf("UD2 exception:\n"); |
1164 |
if (setjmp(jmp_env) == 0) { |
if (setjmp(jmp_env) == 0) { |
1170 |
if (setjmp(jmp_env) == 0) { |
if (setjmp(jmp_env) == 0) { |
1171 |
asm volatile ("int $0xfd"); |
asm volatile ("int $0xfd"); |
1172 |
} |
} |
1173 |
|
if (setjmp(jmp_env) == 0) { |
1174 |
|
asm volatile ("int $0x01"); |
1175 |
|
} |
1176 |
|
if (setjmp(jmp_env) == 0) { |
1177 |
|
asm volatile (".byte 0xcd, 0x03"); |
1178 |
|
} |
1179 |
|
if (setjmp(jmp_env) == 0) { |
1180 |
|
asm volatile ("int $0x04"); |
1181 |
|
} |
1182 |
|
if (setjmp(jmp_env) == 0) { |
1183 |
|
asm volatile ("int $0x05"); |
1184 |
|
} |
1185 |
|
|
1186 |
printf("INT3 exception:\n"); |
printf("INT3 exception:\n"); |
1187 |
if (setjmp(jmp_env) == 0) { |
if (setjmp(jmp_env) == 0) { |