| OLD | NEW |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include <asm/unistd.h> | 5 #include <asm/unistd.h> |
| 6 | 6 |
| 7 | 7 |
| 8 .internal playground$segvSignalHandler | 8 .internal playground$segvSignalHandler |
| 9 .global playground$segvSignalHandler | 9 .global playground$segvSignalHandler |
| 10 playground$segvSignalHandler: | 10 playground$segvSignalHandler: |
| 11 // Inspect instruction at the point where the segmentation fault | 11 // Inspect instruction at the point where the segmentation fault |
| 12 // happened. If it is RDTSC, forward the request to the trusted | 12 // happened. If it is RDTSC, forward the request to the trusted |
| 13 // thread. | 13 // thread. |
| 14 mov $-3, %ebx // request for RDTSC | 14 mov $-3, %ebx // request for RDTSC |
| 15 mov 0xDC(%esp), %ebp // %eip at time of segmentation fault | 15 mov 0xDC(%esp), %ebp // %eip at time of segmentation fault |
| 16 cmpw $0x310F, (%ebp) // RDTSC | 16 cmpw $0x310F, (%ebp) // RDTSC |
| 17 jz 0f | 17 jz 1f |
| 18 cmpw $0x010F, (%ebp) // RDTSCP | 18 cmpw $0x010F, (%ebp) // RDTSCP |
| 19 jnz 10f | 19 jnz 12f |
| 20 cmpb $0xF9, 2(%ebp) | 20 cmpb $0xF9, 2(%ebp) |
| 21 jnz 10f | 21 jnz 12f |
| 22 mov $-4, %ebx // request for RDTSCP | 22 mov $-4, %ebx // request for RDTSCP |
| 23 0: | 23 1: |
| 24 #ifndef NDEBUG | 24 #ifndef NDEBUG |
| 25 lea 100f, %eax | 25 call 2f |
| 26 push %eax | 26 2:addl $(100f-.), 0(%esp) |
| 27 call playground$debugMessage | 27 call playground$debugMessage@PLT |
| 28 sub $4, %esp | 28 sub $4, %esp |
| 29 #else | 29 #else |
| 30 sub $8, %esp // allocate buffer for receiving timestamp | 30 sub $8, %esp // allocate buffer for receiving timestamp |
| 31 #endif | 31 #endif |
| 32 push %ebx | 32 push %ebx |
| 33 mov %fs:16, %ebx // fd = threadFdPub | 33 mov %fs:16, %ebx // fd = threadFdPub |
| 34 mov %esp, %ecx // buf = %esp | 34 mov %esp, %ecx // buf = %esp |
| 35 mov $4, %edx // len = sizeof(int) | 35 mov $4, %edx // len = sizeof(int) |
| 36 1:mov %edx, %eax // NR_write | 36 3:mov %edx, %eax // NR_write |
| 37 int $0x80 | 37 int $0x80 |
| 38 cmp %eax, %edx | 38 cmp %eax, %edx |
| 39 jz 8f | 39 jz 10f |
| 40 cmp $-4, %eax // EINTR | 40 cmp $-4, %eax // EINTR |
| 41 jz 1b | 41 jz 3b |
| 42 2:add $12, %esp // remove temporary buffer from stack | 42 4:add $12, %esp // remove temporary buffer from stack |
| 43 xor %eax, %eax | 43 xor %eax, %eax |
| 44 movl $0, 0xC8(%esp) // %edx at time of segmentation fault | 44 movl $0, 0xC8(%esp) // %edx at time of segmentation fault |
| 45 cmpw $0x310F, (%ebp) // RDTSC | 45 cmpw $0x310F, (%ebp) // RDTSC |
| 46 jz 3f | 46 jz 5f |
| 47 movl $0, 0xCC(%esp) // %ecx at time of segmentation fault | 47 movl $0, 0xCC(%esp) // %ecx at time of segmentation fault |
| 48 3:mov %eax, 0xD0(%esp) // %eax at time of segmentation fault | 48 5:mov %eax, 0xD0(%esp) // %eax at time of segmentation fault |
| 49 4:mov 0xDC(%esp), %ebp // %eip at time of segmentation fault | 49 6:mov 0xDC(%esp), %ebp // %eip at time of segmentation fault |
| 50 addl $2, 0xDC(%esp) // %eip at time of segmentation fault | 50 addl $2, 0xDC(%esp) // %eip at time of segmentation fault |
| 51 cmpw $0x010F, (%ebp) // RDTSCP | 51 cmpw $0x010F, (%ebp) // RDTSCP |
| 52 jnz 5f | 52 jnz 7f |
| 53 addl $1, 0xDC(%esp) // %eip at time of segmentation fault | 53 addl $1, 0xDC(%esp) // %eip at time of segmentation fault |
| 54 5:add $0x4, %esp | 54 7:add $0x4, %esp |
| 55 6:sub $0x1CC, %esp // a legacy signal stack is much larger | 55 8:sub $0x1CC, %esp // a legacy signal stack is much larger |
| 56 mov 0x1CC(%esp), %eax // push signal number | 56 mov 0x1CC(%esp), %eax // push signal number |
| 57 push %eax | 57 push %eax |
| 58 lea 0x270(%esp), %esi // copy siginfo register values | 58 lea 0x270(%esp), %esi // copy siginfo register values |
| 59 lea 0x4(%esp), %edi // into new location | 59 lea 0x4(%esp), %edi // into new location |
| 60 mov $22, %ecx | 60 mov $22, %ecx |
| 61 cld | 61 cld |
| 62 rep movsl | 62 rep movsl |
| 63 mov 0x2C8(%esp), %ebx // copy first half of signal mask | 63 mov 0x2C8(%esp), %ebx // copy first half of signal mask |
| 64 mov %ebx, 0x54(%esp) | 64 mov %ebx, 0x54(%esp) |
| 65 7:pop %eax // remove dummy argument (signo) | 65 9:pop %eax // remove dummy argument (signo) |
| 66 mov $119, %eax // NR_sigreturn | 66 mov $119, %eax // NR_sigreturn |
| 67 int $0x80 | 67 int $0x80 |
| 68 8:mov $12, %edx // len = 3*sizeof(int) | 68 10:mov $12, %edx // len = 3*sizeof(int) |
| 69 9:mov $3, %eax // NR_read | 69 11:mov $3, %eax // NR_read |
| 70 int $0x80 | 70 int $0x80 |
| 71 cmp $-4, %eax // EINTR | 71 cmp $-4, %eax // EINTR |
| 72 jz 9b | 72 jz 11b |
| 73 cmp %eax, %edx | 73 cmp %eax, %edx |
| 74 jnz 2b | 74 jnz 4b |
| 75 pop %eax | 75 pop %eax |
| 76 pop %edx | 76 pop %edx |
| 77 pop %ecx | 77 pop %ecx |
| 78 mov %edx, 0xC8(%esp) // %edx at time of segmentation fault | 78 mov %edx, 0xC8(%esp) // %edx at time of segmentation fault |
| 79 cmpw $0x310F, (%ebp) // RDTSC | 79 cmpw $0x310F, (%ebp) // RDTSC |
| 80 jz 3b | 80 jz 5b |
| 81 mov %ecx, 0xCC(%esp) // %ecx at time of segmentation fault | 81 mov %ecx, 0xCC(%esp) // %ecx at time of segmentation fault |
| 82 jmp 3b | 82 jmp 5b |
| 83 | 83 |
| 84 // If the instruction is INT 0, then this was probably the result | 84 // If the instruction is INT 0, then this was probably the result |
| 85 // of playground::Library being unable to find a way to safely | 85 // of playground::Library being unable to find a way to safely |
| 86 // rewrite the system call instruction. Retrieve the CPU register | 86 // rewrite the system call instruction. Retrieve the CPU register |
| 87 // at the time of the segmentation fault and invoke | 87 // at the time of the segmentation fault and invoke |
| 88 // syscallEntryPointWithFrame(). | 88 // syscallEntryPointWithFrame(). |
| 89 10:cmpw $0x00CD, (%ebp) // INT $0x0 | 89 12:cmpw $0x00CD, (%ebp) // INT $0x0 |
| 90 jnz 20f | 90 jnz 23f |
| 91 cmpl $__NR_clone + 0xF001, 0xD0(%esp) | 91 cmpl $__NR_clone + 0xF001, 0xD0(%esp) |
| 92 jz .L_handle_callback_request | 92 jz .L_handle_callback_request |
| 93 #ifndef NDEBUG | 93 #ifndef NDEBUG |
| 94 lea 200f, %eax | 94 call 1010f |
| 95 push %eax | 95 1010:addl $(200f-.), 0(%esp) |
| 96 call playground$debugMessage | 96 call playground$debugMessage@PLT |
| 97 add $0x4, %esp | 97 add $0x4, %esp |
| 98 #endif | 98 #endif |
| 99 mov 0xD0(%esp), %eax // %eax at time of segmentation fault | 99 mov 0xD0(%esp), %eax // %eax at time of segmentation fault |
| 100 mov 0xC4(%esp), %ebx // %ebx at time of segmentation fault | 100 mov 0xC4(%esp), %ebx // %ebx at time of segmentation fault |
| 101 mov 0xCC(%esp), %ecx // %ecx at time of segmentation fault | 101 mov 0xCC(%esp), %ecx // %ecx at time of segmentation fault |
| 102 mov 0xC8(%esp), %edx // %edx at time of segmentation fault | 102 mov 0xC8(%esp), %edx // %edx at time of segmentation fault |
| 103 mov 0xB8(%esp), %esi // %esi at time of segmentation fault | 103 mov 0xB8(%esp), %esi // %esi at time of segmentation fault |
| 104 mov 0xB4(%esp), %edi // %edi at time of segmentation fault | 104 mov 0xB4(%esp), %edi // %edi at time of segmentation fault |
| 105 mov 0xBC(%esp), %ebp // %ebp at time of segmentation fault | 105 mov 0xBC(%esp), %ebp // %ebp at time of segmentation fault |
| 106 | 106 |
| 107 // Handle sigprocmask() and rt_sigprocmask() | 107 // Handle sigprocmask() and rt_sigprocmask() |
| 108 cmp $175, %eax // NR_rt_sigprocmask | 108 cmp $175, %eax // NR_rt_sigprocmask |
| 109 jnz 11f | 109 jnz 13f |
| 110 mov $-22, %eax // -EINVAL | 110 mov $-22, %eax // -EINVAL |
| 111 cmp $8, %esi // %esi = sigsetsize (8 bytes = 64 signals) | 111 cmp $8, %esi // %esi = sigsetsize (8 bytes = 64 signals) |
| 112 jl 3b | 112 jl 5b |
| 113 jmp 12f | 113 jmp 14f |
| 114 11:cmp $126, %eax // NR_sigprocmask | 114 13:cmp $126, %eax // NR_sigprocmask |
| 115 jnz 16f | 115 jnz 18f |
| 116 mov $-22, %eax | 116 mov $-22, %eax |
| 117 12:mov 0xFC(%esp), %edi // signal mask at time of segmentation fault | 117 14:mov 0xFC(%esp), %edi // signal mask at time of segmentation fault |
| 118 mov 0x100(%esp), %ebp | 118 mov 0x100(%esp), %ebp |
| 119 test %ecx, %ecx // only set mask, if set is non-NULL | 119 test %ecx, %ecx // only set mask, if set is non-NULL |
| 120 jz 15f | 120 jz 17f |
| 121 mov 0(%ecx), %esi | 121 mov 0(%ecx), %esi |
| 122 mov 4(%ecx), %ecx | 122 mov 4(%ecx), %ecx |
| 123 cmp $0, %ebx // %ebx = how (SIG_BLOCK) | 123 cmp $0, %ebx // %ebx = how (SIG_BLOCK) |
| 124 jnz 13f | 124 jnz 15f |
| 125 or %esi, 0xFC(%esp) // signal mask at time of segmentation fault | 125 or %esi, 0xFC(%esp) // signal mask at time of segmentation fault |
| 126 or %ecx, 0x100(%esp) | 126 or %ecx, 0x100(%esp) |
| 127 jmp 15f | 127 jmp 17f |
| 128 13:cmp $1, %ebx // %ebx = how (SIG_UNBLOCK) | 128 15:cmp $1, %ebx // %ebx = how (SIG_UNBLOCK) |
| 129 jnz 14f | 129 jnz 16f |
| 130 xor $-1, %esi | 130 xor $-1, %esi |
| 131 xor $-1, %ecx | 131 xor $-1, %ecx |
| 132 and %esi, 0xFC(%esp) // signal mask at time of segmentation fault | 132 and %esi, 0xFC(%esp) // signal mask at time of segmentation fault |
| 133 and %ecx, 0x100(%esp) | 133 and %ecx, 0x100(%esp) |
| 134 jmp 15f | 134 jmp 17f |
| 135 14:cmp $2, %ebx // %ebx = how (SIG_SETMASK) | 135 16:cmp $2, %ebx // %ebx = how (SIG_SETMASK) |
| 136 jnz 3b | 136 jnz 5b |
| 137 mov %esi, 0xFC(%esp) // signal mask at time of segmentation fault | 137 mov %esi, 0xFC(%esp) // signal mask at time of segmentation fault |
| 138 mov %ecx, 0x100(%esp) | 138 mov %ecx, 0x100(%esp) |
| 139 15:xor %eax, %eax | 139 17:xor %eax, %eax |
| 140 test %edx, %edx // only return old mask, if set is non-NULL | 140 test %edx, %edx // only return old mask, if set is non-NULL |
| 141 jz 3b | 141 jz 5b |
| 142 mov %edi, 0(%edx) // old_set | 142 mov %edi, 0(%edx) // old_set |
| 143 mov %ebp, 4(%edx) | 143 mov %ebp, 4(%edx) |
| 144 jmp 3b | 144 jmp 5b |
| 145 | 145 |
| 146 // Handle sigreturn() and rt_sigreturn() | 146 // Handle sigreturn() and rt_sigreturn() |
| 147 // See syscall.cc for a discussion on how we can emulate rt_sigreturn() | 147 // See syscall.cc for a discussion on how we can emulate rt_sigreturn() |
| 148 // by calling sigreturn() with a suitably adjusted stack. | 148 // by calling sigreturn() with a suitably adjusted stack. |
| 149 16:cmp $119, %eax // NR_sigreturn | 149 18:cmp $119, %eax // NR_sigreturn |
| 150 jnz 17f | 150 jnz 19f |
| 151 mov 0xC0(%esp), %esp // %esp at time of segmentation fault | 151 mov 0xC0(%esp), %esp // %esp at time of segmentation fault |
| 152 int $0x80 // sigreturn() is unrestricted | 152 int $0x80 // sigreturn() is unrestricted |
| 153 17:cmp $173, %eax // NR_rt_sigreturn | 153 19:cmp $173, %eax // NR_rt_sigreturn |
| 154 jnz 18f | 154 jnz 20f |
| 155 mov 0xC0(%esp), %esp // %esp at time of segmentation fault | 155 mov 0xC0(%esp), %esp // %esp at time of segmentation fault |
| 156 sub $4, %esp // add fake return address | 156 sub $4, %esp // add fake return address |
| 157 jmp 4b | 157 jmp 6b |
| 158 | 158 |
| 159 // Copy signal frame onto new stack. In the process, we have to convert | 159 // Copy signal frame onto new stack. In the process, we have to convert |
| 160 // it from an RT signal frame to a legacy signal frame. | 160 // it from an RT signal frame to a legacy signal frame. |
| 161 // See clone.cc for details | 161 // See clone.cc for details |
| 162 18:cmp $120+0xF000, %eax // NR_clone + 0xF000 | 162 20:cmp $120+0xF000, %eax // NR_clone + 0xF000 |
| 163 jnz 19f | 163 jnz 21f |
| 164 lea -0x1C8(%esp), %eax // retain stack frame upon returning | 164 lea -0x1C8(%esp), %eax // retain stack frame upon returning |
| 165 mov %eax, 0xC0(%esp) // %esp at time of segmentation fault | 165 mov %eax, 0xC0(%esp) // %esp at time of segmentation fault |
| 166 jmp 3b | 166 jmp 5b |
| 167 | 167 |
| 168 // Forward system call to syscallEntryPointWithFrame() | 168 // Forward system call to syscallEntryPointWithFrame() |
| 169 19:push $3b | 169 21:call 22f |
| 170 22:subl $(.-5b), 0(%esp) |
| 170 push 0xE0(%esp) // %eip at time of segmentation fault | 171 push 0xE0(%esp) // %eip at time of segmentation fault |
| 171 jmp playground$syscallEntryPointWithFrame | 172 jmp playground$syscallEntryPointWithFrame@PLT |
| 172 | 173 |
| 173 // This was a genuine segmentation fault. Check Sandbox::sa_segv_ for | 174 // This was a genuine segmentation fault. Check Sandbox::sa_segv_ for |
| 174 // what we are supposed to do. | 175 // what we are supposed to do. |
| 175 // In order to implement SA_NODEFER, we have to keep track of recursive | 176 // In order to implement SA_NODEFER, we have to keep track of recursive |
| 176 // calls to SIGSEGV handlers. This means we have to increment a counter | 177 // calls to SIGSEGV handlers. This means we have to increment a counter |
| 177 // before calling the user's signal handler, and decrement it on | 178 // before calling the user's signal handler, and decrement it on |
| 178 // leaving the user's signal handler. | 179 // leaving the user's signal handler. |
| 179 // N.B. We currently do not correctly adjust the SEGV counter, if the | 180 // N.B. We currently do not correctly adjust the SEGV counter, if the |
| 180 // user's signal handler exits in way other than by returning (e.g. by | 181 // user's signal handler exits in way other than by returning (e.g. by |
| 181 // directly calling {,rt_}sigreturn(), or by calling siglongjmp()). | 182 // directly calling {,rt_}sigreturn(), or by calling siglongjmp()). |
| 182 // N.B. On i386, we don't have any guarantees that NX protection works. | 183 // N.B. On i386, we don't have any guarantees that NX protection works. |
| 183 // So, we don't even attempt to fake a correct restorer function. Some | 184 // So, we don't even attempt to fake a correct restorer function. Some |
| 184 // callers might be confused by this and will need fixing for running | 185 // callers might be confused by this and will need fixing for running |
| 185 // inside of the seccomp sandbox. | 186 // inside of the seccomp sandbox. |
| 186 20:lea playground$sa_segv, %eax | 187 23:call 24f |
| 188 24:pop %eax |
| 189 add $(_GLOBAL_OFFSET_TABLE_+(.-24b)), %eax |
| 190 lea playground$sa_segv@GOTOFF(%eax), %eax |
| 187 cmpl $0, 0(%eax) // SIG_DFL | 191 cmpl $0, 0(%eax) // SIG_DFL |
| 188 jz 21f | 192 jz 25f |
| 189 cmpl $1, 0(%eax) // SIG_IGN | 193 cmpl $1, 0(%eax) // SIG_IGN |
| 190 jnz 22f // can't really ignore synchronous signals | 194 jnz 26f // can't really ignore synchronous signals |
| 191 | 195 |
| 192 // Trigger the kernel's default signal disposition. The only way we can | 196 // Trigger the kernel's default signal disposition. The only way we can |
| 193 // do this from seccomp mode is by blocking the signal and retriggering | 197 // do this from seccomp mode is by blocking the signal and retriggering |
| 194 // it. | 198 // it. |
| 195 21:orb $4, 0xFD(%esp) // signal mask at time of segmentation fault | 199 25:orb $4, 0xFD(%esp) // signal mask at time of segmentation fault |
| 196 jmp 5b | 200 jmp 7b |
| 197 | 201 |
| 198 // Check sa_flags: | 202 // Check sa_flags: |
| 199 // - We can ignore SA_NOCLDSTOP, SA_NOCLDWAIT, and SA_RESTART as they | 203 // - We can ignore SA_NOCLDSTOP, SA_NOCLDWAIT, and SA_RESTART as they |
| 200 // do not have any effect for SIGSEGV. | 204 // do not have any effect for SIGSEGV. |
| 201 // - We have to always register our signal handler with SA_NODEFER so | 205 // - We have to always register our signal handler with SA_NODEFER so |
| 202 // that the user's signal handler can make system calls which might | 206 // that the user's signal handler can make system calls which might |
| 203 // require additional help from our SEGV handler. | 207 // require additional help from our SEGV handler. |
| 204 // - If the user's signal handler wasn't supposed to be SA_NODEFER, | 208 // - If the user's signal handler wasn't supposed to be SA_NODEFER, |
| 205 // then we emulate this behavior by keeping track of a recursion | 209 // then we emulate this behavior by keeping track of a recursion |
| 206 // counter. | 210 // counter. |
| 207 // | 211 // |
| 208 // TODO(markus): If/when we add support for sigaltstack(), we have to | 212 // TODO(markus): If/when we add support for sigaltstack(), we have to |
| 209 // handle SA_ONSTACK. | 213 // handle SA_ONSTACK. |
| 210 22:cmpl $0, %fs:0x1040-0x58 // check if we failed inside of SEGV handler | 214 26:cmpl $0, %fs:0x1040-0x58 // check if we failed inside of SEGV handler |
| 211 jnz 21b // if so, then terminate program | 215 jnz 25b // if so, then terminate program |
| 212 mov 0(%eax), %ebx // sa_segv_.sa_sigaction | 216 mov 0(%eax), %ebx // sa_segv_.sa_sigaction |
| 213 mov 4(%eax), %ecx // sa_segv_.sa_flags | 217 mov 4(%eax), %ecx // sa_segv_.sa_flags |
| 214 btl $31, %ecx // SA_RESETHAND | 218 btl $31, %ecx // SA_RESETHAND |
| 215 jnc 23f | 219 jnc 27f |
| 216 movl $0, 0(%eax) // set handler to SIG_DFL | 220 movl $0, 0(%eax) // set handler to SIG_DFL |
| 217 23:btl $30, %ecx // SA_NODEFER | 221 27:btl $30, %ecx // SA_NODEFER |
| 218 jc 26f | 222 jc 32f |
| 219 btl $2, %ecx // SA_SIGINFO | 223 btl $2, %ecx // SA_SIGINFO |
| 220 jnc 24f | 224 jnc 29f |
| 221 movl $27f, 0(%esp) // set appropriate restorer function | 225 add $4, %esp |
| 226 call 28f |
| 227 28:addl $(35f-.), 0(%esp) // set appropriate restorer function |
| 222 incl %fs:0x1040-0x58 // increment recursion counter | 228 incl %fs:0x1040-0x58 // increment recursion counter |
| 223 jmp *%ebx // call user's signal handler | 229 jmp *%ebx // call user's signal handler |
| 224 24:movl $28f, 0(%esp) | 230 29:add $4, %esp |
| 231 call 30f |
| 232 30:addl $(36f-.), 0(%esp) |
| 225 incl %fs:0x1040-0x58 // increment recursion counter | 233 incl %fs:0x1040-0x58 // increment recursion counter |
| 226 | 234 |
| 227 // We always register the signal handler to give us rt-style signal | 235 // We always register the signal handler to give us rt-style signal |
| 228 // frames. But if the user asked for legacy signal frames, we must | 236 // frames. But if the user asked for legacy signal frames, we must |
| 229 // convert the signal frame prior to calling the user's signal handler. | 237 // convert the signal frame prior to calling the user's signal handler. |
| 230 25:sub $0x1C8, %esp // a legacy signal stack is much larger | 238 31:sub $0x1C8, %esp // a legacy signal stack is much larger |
| 231 mov 0x1CC(%esp), %eax // push signal number | 239 mov 0x1CC(%esp), %eax // push signal number |
| 232 push %eax | 240 push %eax |
| 233 mov 0x1CC(%esp), %eax // push restorer function | 241 mov 0x1CC(%esp), %eax // push restorer function |
| 234 push %eax | 242 push %eax |
| 235 lea 0x274(%esp), %esi // copy siginfo register values | 243 lea 0x274(%esp), %esi // copy siginfo register values |
| 236 lea 0x8(%esp), %edi // into new location | 244 lea 0x8(%esp), %edi // into new location |
| 237 mov $22, %ecx | 245 mov $22, %ecx |
| 238 cld | 246 cld |
| 239 rep movsl | 247 rep movsl |
| 240 mov 0x2CC(%esp), %eax // copy first half of signal mask | 248 mov 0x2CC(%esp), %eax // copy first half of signal mask |
| 241 mov %eax, 0x58(%esp) | 249 mov %eax, 0x58(%esp) |
| 242 jmp *%ebx // call user's signal handler | 250 jmp *%ebx // call user's signal handler |
| 243 26:movl $7b, 0(%esp) // set appropriate restorer function | 251 32:add $4, %esp |
| 252 call 33f |
| 253 33:addl $(9b-.), 0(%esp) // set appropriate restorer function |
| 244 btl $2, %ecx // SA_SIGINFO | 254 btl $2, %ecx // SA_SIGINFO |
| 245 jnc 25b | 255 jnc 31b |
| 246 movl $6b, 0(%esp) // set appropriate restorer function | 256 add $4, %esp |
| 257 call 34f |
| 258 34:addl $(8b-.), 0(%esp) // set appropriate restorer function |
| 247 jmp *%ebx // call user's signal handler | 259 jmp *%ebx // call user's signal handler |
| 248 27:decl %fs:0x1040-0x58 | 260 35:decl %fs:0x1040-0x58 |
| 249 jmp 6b | 261 jmp 8b |
| 250 28:decl %fs:0x1040-0x58 | 262 36:decl %fs:0x1040-0x58 |
| 251 jmp 7b | 263 jmp 9b |
| 252 | 264 |
| 253 .L_handle_callback_request: | 265 .L_handle_callback_request: |
| 254 mov 0xC8(%esp), %eax // %edx at time of segmentation fault | 266 mov 0xC8(%esp), %eax // %edx at time of segmentation fault |
| 255 jmp *%eax | 267 jmp *%eax |
| OLD | NEW |