| Index: fault_handler_i386.S
|
| ===================================================================
|
| --- fault_handler_i386.S (revision 167)
|
| +++ fault_handler_i386.S (working copy)
|
| @@ -14,17 +14,17 @@
|
| mov $-3, %ebx // request for RDTSC
|
| mov 0xDC(%esp), %ebp // %eip at time of segmentation fault
|
| cmpw $0x310F, (%ebp) // RDTSC
|
| - jz 0f
|
| + jz 1f
|
| cmpw $0x010F, (%ebp) // RDTSCP
|
| - jnz 10f
|
| + jnz 12f
|
| cmpb $0xF9, 2(%ebp)
|
| - jnz 10f
|
| + jnz 12f
|
| mov $-4, %ebx // request for RDTSCP
|
| - 0:
|
| + 1:
|
| #ifndef NDEBUG
|
| - lea 100f, %eax
|
| - push %eax
|
| - call playground$debugMessage
|
| + call 2f
|
| + 2:addl $(100f-.), 0(%esp)
|
| + call playground$debugMessage@PLT
|
| sub $4, %esp
|
| #else
|
| sub $8, %esp // allocate buffer for receiving timestamp
|
| @@ -33,26 +33,26 @@
|
| mov %fs:16, %ebx // fd = threadFdPub
|
| mov %esp, %ecx // buf = %esp
|
| mov $4, %edx // len = sizeof(int)
|
| - 1:mov %edx, %eax // NR_write
|
| + 3:mov %edx, %eax // NR_write
|
| int $0x80
|
| cmp %eax, %edx
|
| - jz 8f
|
| + jz 10f
|
| cmp $-4, %eax // EINTR
|
| - jz 1b
|
| - 2:add $12, %esp // remove temporary buffer from stack
|
| + jz 3b
|
| + 4:add $12, %esp // remove temporary buffer from stack
|
| xor %eax, %eax
|
| movl $0, 0xC8(%esp) // %edx at time of segmentation fault
|
| cmpw $0x310F, (%ebp) // RDTSC
|
| - jz 3f
|
| + jz 5f
|
| movl $0, 0xCC(%esp) // %ecx at time of segmentation fault
|
| - 3:mov %eax, 0xD0(%esp) // %eax at time of segmentation fault
|
| - 4:mov 0xDC(%esp), %ebp // %eip at time of segmentation fault
|
| + 5:mov %eax, 0xD0(%esp) // %eax at time of segmentation fault
|
| + 6:mov 0xDC(%esp), %ebp // %eip at time of segmentation fault
|
| addl $2, 0xDC(%esp) // %eip at time of segmentation fault
|
| cmpw $0x010F, (%ebp) // RDTSCP
|
| - jnz 5f
|
| + jnz 7f
|
| addl $1, 0xDC(%esp) // %eip at time of segmentation fault
|
| - 5:add $0x4, %esp
|
| - 6:sub $0x1CC, %esp // a legacy signal stack is much larger
|
| + 7:add $0x4, %esp
|
| + 8:sub $0x1CC, %esp // a legacy signal stack is much larger
|
| mov 0x1CC(%esp), %eax // push signal number
|
| push %eax
|
| lea 0x270(%esp), %esi // copy siginfo register values
|
| @@ -62,38 +62,38 @@
|
| rep movsl
|
| mov 0x2C8(%esp), %ebx // copy first half of signal mask
|
| mov %ebx, 0x54(%esp)
|
| - 7:pop %eax // remove dummy argument (signo)
|
| + 9:pop %eax // remove dummy argument (signo)
|
| mov $119, %eax // NR_sigreturn
|
| int $0x80
|
| - 8:mov $12, %edx // len = 3*sizeof(int)
|
| - 9:mov $3, %eax // NR_read
|
| + 10:mov $12, %edx // len = 3*sizeof(int)
|
| + 11:mov $3, %eax // NR_read
|
| int $0x80
|
| cmp $-4, %eax // EINTR
|
| - jz 9b
|
| + jz 11b
|
| cmp %eax, %edx
|
| - jnz 2b
|
| + jnz 4b
|
| pop %eax
|
| pop %edx
|
| pop %ecx
|
| mov %edx, 0xC8(%esp) // %edx at time of segmentation fault
|
| cmpw $0x310F, (%ebp) // RDTSC
|
| - jz 3b
|
| + jz 5b
|
| mov %ecx, 0xCC(%esp) // %ecx at time of segmentation fault
|
| - jmp 3b
|
| + jmp 5b
|
|
|
| // If the instruction is INT 0, then this was probably the result
|
| // of playground::Library being unable to find a way to safely
|
| // rewrite the system call instruction. Retrieve the CPU register
|
| // at the time of the segmentation fault and invoke
|
| // syscallEntryPointWithFrame().
|
| - 10:cmpw $0x00CD, (%ebp) // INT $0x0
|
| - jnz 20f
|
| + 12:cmpw $0x00CD, (%ebp) // INT $0x0
|
| + jnz 23f
|
| cmpl $__NR_clone + 0xF001, 0xD0(%esp)
|
| jz .L_handle_callback_request
|
| #ifndef NDEBUG
|
| - lea 200f, %eax
|
| - push %eax
|
| - call playground$debugMessage
|
| + call 1010f
|
| + 1010:addl $(200f-.), 0(%esp)
|
| + call playground$debugMessage@PLT
|
| add $0x4, %esp
|
| #endif
|
| mov 0xD0(%esp), %eax // %eax at time of segmentation fault
|
| @@ -106,69 +106,70 @@
|
|
|
| // Handle sigprocmask() and rt_sigprocmask()
|
| cmp $175, %eax // NR_rt_sigprocmask
|
| - jnz 11f
|
| + jnz 13f
|
| mov $-22, %eax // -EINVAL
|
| cmp $8, %esi // %esi = sigsetsize (8 bytes = 64 signals)
|
| - jl 3b
|
| - jmp 12f
|
| - 11:cmp $126, %eax // NR_sigprocmask
|
| - jnz 16f
|
| + jl 5b
|
| + jmp 14f
|
| + 13:cmp $126, %eax // NR_sigprocmask
|
| + jnz 18f
|
| mov $-22, %eax
|
| - 12:mov 0xFC(%esp), %edi // signal mask at time of segmentation fault
|
| + 14:mov 0xFC(%esp), %edi // signal mask at time of segmentation fault
|
| mov 0x100(%esp), %ebp
|
| test %ecx, %ecx // only set mask, if set is non-NULL
|
| - jz 15f
|
| + jz 17f
|
| mov 0(%ecx), %esi
|
| mov 4(%ecx), %ecx
|
| cmp $0, %ebx // %ebx = how (SIG_BLOCK)
|
| - jnz 13f
|
| + jnz 15f
|
| or %esi, 0xFC(%esp) // signal mask at time of segmentation fault
|
| or %ecx, 0x100(%esp)
|
| - jmp 15f
|
| - 13:cmp $1, %ebx // %ebx = how (SIG_UNBLOCK)
|
| - jnz 14f
|
| + jmp 17f
|
| + 15:cmp $1, %ebx // %ebx = how (SIG_UNBLOCK)
|
| + jnz 16f
|
| xor $-1, %esi
|
| xor $-1, %ecx
|
| and %esi, 0xFC(%esp) // signal mask at time of segmentation fault
|
| and %ecx, 0x100(%esp)
|
| - jmp 15f
|
| - 14:cmp $2, %ebx // %ebx = how (SIG_SETMASK)
|
| - jnz 3b
|
| + jmp 17f
|
| + 16:cmp $2, %ebx // %ebx = how (SIG_SETMASK)
|
| + jnz 5b
|
| mov %esi, 0xFC(%esp) // signal mask at time of segmentation fault
|
| mov %ecx, 0x100(%esp)
|
| - 15:xor %eax, %eax
|
| + 17:xor %eax, %eax
|
| test %edx, %edx // only return old mask, if set is non-NULL
|
| - jz 3b
|
| + jz 5b
|
| mov %edi, 0(%edx) // old_set
|
| mov %ebp, 4(%edx)
|
| - jmp 3b
|
| + jmp 5b
|
|
|
| // Handle sigreturn() and rt_sigreturn()
|
| // See syscall.cc for a discussion on how we can emulate rt_sigreturn()
|
| // by calling sigreturn() with a suitably adjusted stack.
|
| - 16:cmp $119, %eax // NR_sigreturn
|
| - jnz 17f
|
| + 18:cmp $119, %eax // NR_sigreturn
|
| + jnz 19f
|
| mov 0xC0(%esp), %esp // %esp at time of segmentation fault
|
| int $0x80 // sigreturn() is unrestricted
|
| - 17:cmp $173, %eax // NR_rt_sigreturn
|
| - jnz 18f
|
| + 19:cmp $173, %eax // NR_rt_sigreturn
|
| + jnz 20f
|
| mov 0xC0(%esp), %esp // %esp at time of segmentation fault
|
| sub $4, %esp // add fake return address
|
| - jmp 4b
|
| + jmp 6b
|
|
|
| // Copy signal frame onto new stack. In the process, we have to convert
|
| // it from an RT signal frame to a legacy signal frame.
|
| // See clone.cc for details
|
| - 18:cmp $120+0xF000, %eax // NR_clone + 0xF000
|
| - jnz 19f
|
| + 20:cmp $120+0xF000, %eax // NR_clone + 0xF000
|
| + jnz 21f
|
| lea -0x1C8(%esp), %eax // retain stack frame upon returning
|
| mov %eax, 0xC0(%esp) // %esp at time of segmentation fault
|
| - jmp 3b
|
| + jmp 5b
|
|
|
| // Forward system call to syscallEntryPointWithFrame()
|
| - 19:push $3b
|
| + 21:call 22f
|
| + 22:subl $(.-5b), 0(%esp)
|
| push 0xE0(%esp) // %eip at time of segmentation fault
|
| - jmp playground$syscallEntryPointWithFrame
|
| + jmp playground$syscallEntryPointWithFrame@PLT
|
|
|
| // This was a genuine segmentation fault. Check Sandbox::sa_segv_ for
|
| // what we are supposed to do.
|
| @@ -183,17 +184,20 @@
|
| // So, we don't even attempt to fake a correct restorer function. Some
|
| // callers might be confused by this and will need fixing for running
|
| // inside of the seccomp sandbox.
|
| - 20:lea playground$sa_segv, %eax
|
| + 23:call 24f
|
| + 24:pop %eax
|
| + add $(_GLOBAL_OFFSET_TABLE_+(.-24b)), %eax
|
| + lea playground$sa_segv@GOTOFF(%eax), %eax
|
| cmpl $0, 0(%eax) // SIG_DFL
|
| - jz 21f
|
| + jz 25f
|
| cmpl $1, 0(%eax) // SIG_IGN
|
| - jnz 22f // can't really ignore synchronous signals
|
| + jnz 26f // can't really ignore synchronous signals
|
|
|
| // Trigger the kernel's default signal disposition. The only way we can
|
| // do this from seccomp mode is by blocking the signal and retriggering
|
| // it.
|
| - 21:orb $4, 0xFD(%esp) // signal mask at time of segmentation fault
|
| - jmp 5b
|
| + 25:orb $4, 0xFD(%esp) // signal mask at time of segmentation fault
|
| + jmp 7b
|
|
|
| // Check sa_flags:
|
| // - We can ignore SA_NOCLDSTOP, SA_NOCLDWAIT, and SA_RESTART as they
|
| @@ -207,27 +211,31 @@
|
| //
|
| // TODO(markus): If/when we add support for sigaltstack(), we have to
|
| // handle SA_ONSTACK.
|
| - 22:cmpl $0, %fs:0x1040-0x58 // check if we failed inside of SEGV handler
|
| - jnz 21b // if so, then terminate program
|
| + 26:cmpl $0, %fs:0x1040-0x58 // check if we failed inside of SEGV handler
|
| + jnz 25b // if so, then terminate program
|
| mov 0(%eax), %ebx // sa_segv_.sa_sigaction
|
| mov 4(%eax), %ecx // sa_segv_.sa_flags
|
| btl $31, %ecx // SA_RESETHAND
|
| - jnc 23f
|
| + jnc 27f
|
| movl $0, 0(%eax) // set handler to SIG_DFL
|
| - 23:btl $30, %ecx // SA_NODEFER
|
| - jc 26f
|
| + 27:btl $30, %ecx // SA_NODEFER
|
| + jc 32f
|
| btl $2, %ecx // SA_SIGINFO
|
| - jnc 24f
|
| - movl $27f, 0(%esp) // set appropriate restorer function
|
| + jnc 29f
|
| + add $4, %esp
|
| + call 28f
|
| + 28:addl $(35f-.), 0(%esp) // set appropriate restorer function
|
| incl %fs:0x1040-0x58 // increment recursion counter
|
| jmp *%ebx // call user's signal handler
|
| - 24:movl $28f, 0(%esp)
|
| + 29:add $4, %esp
|
| + call 30f
|
| + 30:addl $(36f-.), 0(%esp)
|
| incl %fs:0x1040-0x58 // increment recursion counter
|
|
|
| // We always register the signal handler to give us rt-style signal
|
| // frames. But if the user asked for legacy signal frames, we must
|
| // convert the signal frame prior to calling the user's signal handler.
|
| - 25:sub $0x1C8, %esp // a legacy signal stack is much larger
|
| + 31:sub $0x1C8, %esp // a legacy signal stack is much larger
|
| mov 0x1CC(%esp), %eax // push signal number
|
| push %eax
|
| mov 0x1CC(%esp), %eax // push restorer function
|
| @@ -240,15 +248,19 @@
|
| mov 0x2CC(%esp), %eax // copy first half of signal mask
|
| mov %eax, 0x58(%esp)
|
| jmp *%ebx // call user's signal handler
|
| - 26:movl $7b, 0(%esp) // set appropriate restorer function
|
| + 32:add $4, %esp
|
| + call 33f
|
| + 33:addl $(9b-.), 0(%esp) // set appropriate restorer function
|
| btl $2, %ecx // SA_SIGINFO
|
| - jnc 25b
|
| - movl $6b, 0(%esp) // set appropriate restorer function
|
| + jnc 31b
|
| + add $4, %esp
|
| + call 34f
|
| + 34:addl $(8b-.), 0(%esp) // set appropriate restorer function
|
| jmp *%ebx // call user's signal handler
|
| - 27:decl %fs:0x1040-0x58
|
| - jmp 6b
|
| - 28:decl %fs:0x1040-0x58
|
| - jmp 7b
|
| + 35:decl %fs:0x1040-0x58
|
| + jmp 8b
|
| + 36:decl %fs:0x1040-0x58
|
| + jmp 9b
|
|
|
| .L_handle_callback_request:
|
| mov 0xC8(%esp), %eax // %edx at time of segmentation fault
|
|
|