win: Use inline asm instead of ml.exe for SafeTerminateProcess()

This upstreams
912c9907d5
(slightly modified).

Bug: chromium:762167
Change-Id: I69c605f693da8691d32222b5617f62637c1c2dcd
Reviewed-on: https://chromium-review.googlesource.com/734100
Reviewed-by: Mark Mentovai <mark@chromium.org>
Commit-Queue: Mark Mentovai <mark@chromium.org>
This commit is contained in:
Mark Mentovai 2017-10-23 14:50:18 -04:00 committed by Commit Bot
parent ce084d37c8
commit 55133d332b
3 changed files with 52 additions and 76 deletions

View File

@ -245,7 +245,7 @@
'win/process_structs.h', 'win/process_structs.h',
'win/registration_protocol_win.cc', 'win/registration_protocol_win.cc',
'win/registration_protocol_win.h', 'win/registration_protocol_win.h',
'win/safe_terminate_process.asm', 'win/safe_terminate_process.cc',
'win/safe_terminate_process.h', 'win/safe_terminate_process.h',
'win/scoped_handle.cc', 'win/scoped_handle.cc',
'win/scoped_handle.h', 'win/scoped_handle.h',
@ -355,7 +355,6 @@
}, { # else: OS!="win" }, { # else: OS!="win"
'sources!': [ 'sources!': [
'win/capture_context.asm', 'win/capture_context.asm',
'win/safe_terminate_process.asm',
], ],
}], }],
['OS=="linux"', { ['OS=="linux"', {

View File

@ -1,74 +0,0 @@
; Copyright 2017 The Crashpad Authors. All rights reserved.
;
; Licensed under the Apache License, Version 2.0 (the "License");
; you may not use this file except in compliance with the License.
; You may obtain a copy of the License at
;
; http://www.apache.org/licenses/LICENSE-2.0
;
; Unless required by applicable law or agreed to in writing, software
; distributed under the License is distributed on an "AS IS" BASIS,
; WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
; See the License for the specific language governing permissions and
; limitations under the License.
; Detect ml64 assembling for x86_64 by checking for rax.
ifdef rax
_M_X64 equ 1
else
_M_IX86 equ 1
endif
ifdef _M_IX86
.586
.xmm
.model flat
includelib kernel32.lib
extern __imp__TerminateProcess@8:proc
; namespace crashpad {
; bool SafeTerminateProcess(HANDLE process, UINT exit_code);
; } // namespace crashpad
SAFETERMINATEPROCESS_SYMBOL equ ?SafeTerminateProcess@crashpad@@YA_NPAXI@Z
_TEXT segment
public SAFETERMINATEPROCESS_SYMBOL
SAFETERMINATEPROCESS_SYMBOL proc
; This function is written in assembler source because its important for it
; to not be inlined, for it to allocate a stack frame, and most critically,
; for it to not trust esp on return from TerminateProcess().
; __declspec(noinline) can prevent inlining and #pragma optimize("y", off) can
; disable frame pointer omission, but theres no way to force a C compiler to
; distrust esp, and even if there was a way, itd probably be fragile.
push ebp
mov ebp, esp
push [ebp+12]
push [ebp+8]
call dword ptr [__imp__TerminateProcess@8]
; Convert from BOOL to bool.
test eax, eax
setne al
; TerminateProcess() is supposed to be stdcall (callee clean-up), and esp and
; ebp are expected to already be equal. But if its been patched badly by
; something thats cdecl (caller clean-up), this next move will get things
; back on track.
mov esp, ebp
pop ebp
ret
SAFETERMINATEPROCESS_SYMBOL endp
_TEXT ends
endif
end

View File

@ -0,0 +1,51 @@
// Copyright 2017 The Crashpad Authors. All rights reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#include "util/win/safe_terminate_process.h"
#if defined(ARCH_CPU_X86)
namespace crashpad {
// This function is written in assembler source because its important for it to
// not be inlined, for it to allocate a stack frame, and most critically, for it
// to not trust esp on return from TerminateProcess(). __declspec(naked)
// conveniently prevents inlining and allows control of stack layout.
__declspec(naked) bool SafeTerminateProcess(HANDLE process, UINT exit_code) {
__asm {
push ebp
mov ebp, esp
push [ebp+12]
push [ebp+8]
call TerminateProcess
// Convert from BOOL to bool.
test eax, eax
setne al
// TerminateProcess() is supposed to be stdcall (callee clean-up), and esp
// and ebp are expected to already be equal. But if its been patched badly
// by something thats cdecl (caller clean-up), this next move will get
// things back on track.
mov esp, ebp
pop ebp
ret
}
}
} // namespace crashpad
#endif // defined(ARCH_CPU_X86)