| Index: syscall_entrypoint.cc
|
| ===================================================================
|
| --- syscall_entrypoint.cc (revision 167)
|
| +++ syscall_entrypoint.cc (working copy)
|
| @@ -176,7 +176,7 @@
|
| "mov %ebx, %eax\n" // NR_exit
|
| "jmp 0b\n"
|
| "1:cmp $173, %eax\n" // NR_rt_sigreturn
|
| - "jnz 3f\n"
|
| + "jnz 4f\n"
|
|
|
| // Convert rt_sigframe into sigframe, allowing us to call sigreturn().
|
| // This is possible since the first part of signal stack frames have
|
| @@ -202,19 +202,21 @@
|
| "rep movsl\n"
|
| "mov 0x2C8(%esp), %ebx\n" // copy first half of signal mask
|
| "mov %ebx, 0x54(%esp)\n"
|
| - "lea 2f, %esi\n"
|
| + "call 2f\n"
|
| + "2:pop %esi\n"
|
| + "add $(3f-2b), %esi\n"
|
| "push %esi\n" // push restorer function
|
| "lea 0x2D4(%esp), %edi\n" // patch up retcode magic numbers
|
| "movb $2, %cl\n"
|
| "rep movsl\n"
|
| "ret\n" // return to restorer function
|
| - "2:pop %eax\n" // remove dummy argument (signo)
|
| + "3:pop %eax\n" // remove dummy argument (signo)
|
| "mov $119, %eax\n" // NR_sigaction
|
| "int $0x80\n"
|
|
|
|
|
| // Preserve all registers
|
| - "3:push %ebp\n"
|
| + "4:push %ebp\n"
|
| "push $0xDEADBEEF\n" // marker used by breakpad
|
| "push %ebx\n"
|
| "push %ecx\n"
|
| @@ -242,8 +244,12 @@
|
| "push %eax\n"
|
|
|
| // Check range of system call
|
| - "cmp playground$maxSyscall, %eax\n"
|
| - "ja 9f\n"
|
| + "call 5f\n"
|
| + "5:pop %edx\n"
|
| + "add $(_GLOBAL_OFFSET_TABLE_+(.-5b)), %edx\n"
|
| + "mov playground$maxSyscall@GOT(%edx), %edx\n"
|
| + "cmp 0(%edx), %eax\n"
|
| + "ja 14f\n"
|
|
|
| // We often have long sequences of calls to gettimeofday(). This is
|
| // needlessly expensive. Coalesce them into a single call.
|
| @@ -257,9 +263,9 @@
|
| // or maybe, if we have recently seen requests to compute
|
| // the time. There might be a repeated pattern of those.
|
| "cmp $78, %eax\n" // __NR_gettimeofday
|
| - "jnz 6f\n"
|
| + "jnz 10f\n"
|
| "cmp %eax, %fs:0x102C-0x58\n" // last system call
|
| - "jnz 4f\n"
|
| + "jnz 7f\n"
|
|
|
| // This system call and the last system call prior to this one both are
|
| // calls to gettimeofday(). Try to avoid making the new call and just
|
| @@ -267,44 +273,50 @@
|
| // Just in case the caller is spinning on the result from gettimeofday(),
|
| // every so often, call the actual system call.
|
| "decl %fs:0x1030-0x58\n" // countdown calls to gettimofday()
|
| - "jz 4f\n"
|
| + "jz 7f\n"
|
|
|
| // Atomically read the 64bit word representing last-known timestamp and
|
| // return it to the caller. On x86-32 this is a little more complicated and
|
| // requires the use of the cmpxchg8b instruction.
|
| "mov %ebx, %eax\n"
|
| "mov %ecx, %edx\n"
|
| - "lock; cmpxchg8b 100f\n"
|
| + "call 6f\n"
|
| + "6:pop %ebp\n"
|
| + "add $(100f-6b), %ebp\n"
|
| + "lock; cmpxchg8b 0(%ebp)\n"
|
| "mov %eax, 0(%ebx)\n"
|
| "mov %edx, 4(%ebx)\n"
|
| "xor %eax, %eax\n"
|
| "add $28, %esp\n"
|
| - "jmp 8f\n"
|
| + "jmp 13f\n"
|
|
|
| // This is a call to gettimeofday(), but we don't have a valid cached
|
| // result, yet.
|
| - "4:mov %eax, %fs:0x102C-0x58\n" // remember syscall number
|
| + "7:mov %eax, %fs:0x102C-0x58\n" // remember syscall number
|
| "movl $500, %fs:0x1030-0x58\n" // make system call, each 500 invocations
|
| - "call playground$defaultSystemCallHandler\n"
|
| + "call playground$defaultSystemCallHandler@PLT\n"
|
|
|
| // Returned from gettimeofday(). Remember return value, in case the
|
| // application calls us again right away.
|
| // Again, this has to happen atomically and requires cmpxchg8b.
|
| "mov 4(%ebx), %ecx\n"
|
| "mov 0(%ebx), %ebx\n"
|
| - "mov 100f, %eax\n"
|
| - "mov 101f, %edx\n"
|
| - "5:lock; cmpxchg8b 100f\n"
|
| - "jnz 5b\n"
|
| + "call 8f\n"
|
| + "8:pop %ebp\n"
|
| + "add $(100f-8b), %ebp\n"
|
| + "mov 0(%ebp), %eax\n"
|
| + "mov 4(%ebp), %edx\n"
|
| + "9:lock; cmpxchg8b 0(%ebp)\n"
|
| + "jnz 9b\n"
|
| "xor %eax, %eax\n"
|
| - "jmp 10f\n"
|
| + "jmp 15f\n"
|
|
|
| // Remember the number of the last system call made. We deliberately do
|
| // not remember calls to gettid(), as we have often seen long sequences
|
| // of calls to just gettimeofday() and gettid(). In that situation, we
|
| // would still like to coalesce the gettimeofday() calls.
|
| - "6:cmp $224, %eax\n" // __NR_gettid
|
| - "jz 7f\n"
|
| + "10:cmp $224, %eax\n" // __NR_gettid
|
| + "jz 11f\n"
|
| "mov %eax, %fs:0x102C-0x58\n" // remember syscall number
|
|
|
| // Retrieve function call from system call table (c.f.system_call_table.cc)
|
| @@ -312,21 +324,24 @@
|
| // that should be handled by the defaultSystemCallHandler(); minus one
|
| // for unrestricted system calls that need to be forwarded to the trusted
|
| // thread; and function pointers to specific handler functions.
|
| - "7:shl $3, %eax\n"
|
| - "mov playground$syscallTable, %ebx\n"
|
| - "add %ebx, %eax\n"
|
| + "11:shl $3, %eax\n"
|
| + "call 12f\n"
|
| + "12:pop %ebx\n"
|
| + "add $(_GLOBAL_OFFSET_TABLE_+(.-12b)), %ebx\n"
|
| + "mov playground$syscallTable@GOT(%ebx), %ebx\n"
|
| + "add 0(%ebx), %eax\n"
|
| "mov 0(%eax), %eax\n"
|
|
|
| // Jump to function if non-null and not UNRESTRICTED_SYSCALL, otherwise
|
| // jump to fallback handler.
|
| "cmp $1, %eax\n"
|
| - "jbe 9f\n"
|
| + "jbe 14f\n"
|
| "add $4, %esp\n"
|
| "call *%eax\n"
|
| "add $24, %esp\n"
|
|
|
| // Restore CPU registers, except for %eax which was set by the system call.
|
| - "8:pop %esp\n"
|
| + "13:pop %esp\n"
|
| "pop %edi\n"
|
| "pop %esi\n"
|
| "pop %edx\n"
|
| @@ -343,14 +358,13 @@
|
| "ret\n"
|
|
|
| // Call default handler.
|
| - "9:call playground$defaultSystemCallHandler\n"
|
| - "10:add $28, %esp\n"
|
| - "jmp 8b\n"
|
| + "14:call playground$defaultSystemCallHandler@PLT\n"
|
| + "15:add $28, %esp\n"
|
| + "jmp 13b\n"
|
|
|
| ".pushsection \".bss\"\n"
|
| ".balign 8\n"
|
| -"100:.byte 0, 0, 0, 0\n"
|
| -"101:.byte 0, 0, 0, 0\n"
|
| +"100:.byte 0, 0, 0, 0, 0, 0, 0, 0\n"
|
| ".popsection\n"
|
|
|
| #else
|
|
|