Statistics
| Branch: | Revision:

root / tests / testsig.c @ 394411ac

History | View | Annotate | Download (4.7 kB)

1
#define _GNU_SOURCE
2
#include <stdlib.h>
3
#include <stdio.h>
4
#include <string.h>
5
#include <signal.h>
6
#include <unistd.h>
7
#include <setjmp.h>
8
#include <sys/ucontext.h>
9

    
10
jmp_buf jmp_env;
11

    
12
void alarm_handler(int sig)
13
{
14
    printf("alarm signal=%d\n", sig);
15
    alarm(1);
16
}
17

    
18
#ifndef REG_EAX
19
#define REG_EAX EAX
20
#define REG_EBX EBX
21
#define REG_ECX ECX
22
#define REG_EDX EDX
23
#define REG_ESI ESI
24
#define REG_EDI EDI
25
#define REG_EBP EBP
26
#define REG_ESP ESP
27
#define REG_EIP EIP
28
#define REG_EFL EFL
29
#define REG_TRAPNO TRAPNO
30
#define REG_ERR ERR
31
#endif
32

    
33
void dump_regs(struct ucontext *uc)
34
{
35
    printf("EAX=%08x EBX=%08x ECX=%08x EDX=%08x\n"
36
           "ESI=%08x EDI=%08x EBP=%08x ESP=%08x\n"
37
           "EFL=%08x EIP=%08x trapno=%02x err=%08x\n",
38
           uc->uc_mcontext.gregs[REG_EAX],
39
           uc->uc_mcontext.gregs[REG_EBX],
40
           uc->uc_mcontext.gregs[REG_ECX],
41
           uc->uc_mcontext.gregs[REG_EDX],
42
           uc->uc_mcontext.gregs[REG_ESI],
43
           uc->uc_mcontext.gregs[REG_EDI],
44
           uc->uc_mcontext.gregs[REG_EBP],
45
           uc->uc_mcontext.gregs[REG_ESP],
46
           uc->uc_mcontext.gregs[REG_EFL],
47
           uc->uc_mcontext.gregs[REG_EIP],
48
           uc->uc_mcontext.gregs[REG_TRAPNO],
49
           uc->uc_mcontext.gregs[REG_ERR]);
50
}
51

    
52
void sig_handler(int sig, siginfo_t *info, void *puc)
53
{
54
    struct ucontext *uc = puc;
55

    
56
    printf("%s: si_signo=%d si_errno=%d si_code=%d si_addr=0x%08lx\n",
57
           strsignal(info->si_signo),
58
           info->si_signo, info->si_errno, info->si_code, 
59
           (unsigned long)info->si_addr);
60
    dump_regs(uc);
61
    longjmp(jmp_env, 1);
62
}
63

    
64
int v1;
65
int tab[2];
66

    
67
int main(int argc, char **argv)
68
{
69
    struct sigaction act;
70
    volatile int val;
71
    
72
    act.sa_sigaction = sig_handler;
73
    sigemptyset(&act.sa_mask);
74
    act.sa_flags = SA_SIGINFO;
75
    sigaction(SIGFPE, &act, NULL);
76
    sigaction(SIGILL, &act, NULL);
77
    sigaction(SIGSEGV, &act, NULL);
78
    sigaction(SIGTRAP, &act, NULL);
79

    
80
    /* test division by zero reporting */
81
    if (setjmp(jmp_env) == 0) {
82
        /* now divide by zero */
83
        v1 = 0;
84
        v1 = 2 / v1;
85
    }
86

    
87
    /* test illegal instruction reporting */
88
    if (setjmp(jmp_env) == 0) {
89
        /* now execute an invalid instruction */
90
        asm volatile("ud2");
91
    }
92
    
93
    /* test SEGV reporting */
94
    if (setjmp(jmp_env) == 0) {
95
        /* now store in an invalid address */
96
        *(char *)0x1234 = 1;
97
    }
98

    
99
    /* test SEGV reporting */
100
    if (setjmp(jmp_env) == 0) {
101
        /* read from an invalid address */
102
        v1 = *(char *)0x1234;
103
    }
104
    
105
    printf("segment GPF exception:\n");
106
    if (setjmp(jmp_env) == 0) {
107
        /* load an invalid segment */
108
        asm volatile ("movl %0, %%fs" : : "r" ((0x1234 << 3) | 0));
109
    }
110

    
111
    printf("INT exception:\n");
112
    if (setjmp(jmp_env) == 0) {
113
        asm volatile ("int $0xfd");
114
    }
115

    
116
    printf("INT3 exception:\n");
117
    if (setjmp(jmp_env) == 0) {
118
        asm volatile ("int3");
119
    }
120

    
121
    printf("CLI exception:\n");
122
    if (setjmp(jmp_env) == 0) {
123
        asm volatile ("cli");
124
    }
125

    
126
    printf("STI exception:\n");
127
    if (setjmp(jmp_env) == 0) {
128
        asm volatile ("cli");
129
    }
130

    
131
    printf("INTO exception:\n");
132
    if (setjmp(jmp_env) == 0) {
133
        /* overflow exception */
134
        asm volatile ("addl $1, %0 ; into" : : "r" (0x7fffffff));
135
    }
136

    
137
    printf("BOUND exception:\n");
138
    if (setjmp(jmp_env) == 0) {
139
        /* bound exception */
140
        tab[0] = 1;
141
        tab[1] = 10;
142
        asm volatile ("bound %0, %1" : : "r" (11), "m" (tab));
143
    }
144

    
145
    printf("OUTB exception:\n");
146
    if (setjmp(jmp_env) == 0) {
147
        asm volatile ("outb %%al, %%dx" : : "d" (0x4321), "a" (0));
148
    }
149

    
150
    printf("INB exception:\n");
151
    if (setjmp(jmp_env) == 0) {
152
        asm volatile ("inb %%dx, %%al" : "=a" (val) : "d" (0x4321));
153
    }
154

    
155
    printf("REP OUTSB exception:\n");
156
    if (setjmp(jmp_env) == 0) {
157
        asm volatile ("rep outsb" : : "d" (0x4321), "S" (tab), "c" (1));
158
    }
159

    
160
    printf("REP INSB exception:\n");
161
    if (setjmp(jmp_env) == 0) {
162
        asm volatile ("rep insb" : : "d" (0x4321), "D" (tab), "c" (1));
163
    }
164

    
165
    printf("HLT exception:\n");
166
    if (setjmp(jmp_env) == 0) {
167
        asm volatile ("hlt");
168
    }
169

    
170
    printf("single step exception:\n");
171
    val = 0;
172
    if (setjmp(jmp_env) == 0) {
173
        asm volatile ("pushf\n"
174
                      "orl $0x00100, (%%esp)\n"
175
                      "popf\n"
176
                      "movl $0xabcd, %0\n" : "=m" (val) : : "cc", "memory");
177
    }
178
    printf("val=0x%x\n", val);
179
    
180
#if 1
181
    {
182
        int i;
183
        act.sa_handler = alarm_handler;
184
        sigemptyset(&act.sa_mask);
185
        act.sa_flags = 0;
186
        sigaction(SIGALRM, &act, NULL);
187
        alarm(1);
188
        for(i = 0;i < 2; i++) {
189
            sleep(1);
190
        }
191
    }
192
#endif
193
    return 0;
194
}