diff --git a/util/BUILD.gn b/util/BUILD.gn index 00c52e1e..86ae6793 100644 --- a/util/BUILD.gn +++ b/util/BUILD.gn @@ -405,8 +405,17 @@ static_library("util") { "win/safe_terminate_process.asm", ] } else { - # TODO: Add assembly code of CaptureContext for Windows ARM64. - sources += [ "misc/capture_context_broken.cc" ] + # Most Crashpad builds use Microsoft's armasm64.exe macro assembler for + # .asm source files. When building in Chromium, clang-cl is used as the + # assembler instead. Since the two assemblers recognize different + # assembly dialects, the same .asm file can't be used for each. As a + # workaround, use a prebuilt .obj file when the Microsoft-dialect + # assembler isn't available. + if (crashpad_is_in_chromium) { + sources += [ "misc/capture_context_win_arm64.obj" ] + } else { + sources += [ "misc/capture_context_win_arm64.asm" ] + } } } else { sources += [ diff --git a/util/misc/capture_context_fuchsia.S b/util/misc/capture_context_fuchsia.S index 21aefad0..0ebc7f7f 100644 --- a/util/misc/capture_context_fuchsia.S +++ b/util/misc/capture_context_fuchsia.S @@ -116,7 +116,7 @@ CAPTURECONTEXT_SYMBOL: movq 0x90(%rdi), %rax movq 0x28(%rdi), %r8 - // TODO(scottmg): save floating-point registers. + // TODO(https://crashpad.chromium.org/bug/300): save floating-point registers. popfq @@ -166,7 +166,7 @@ CAPTURECONTEXT_SYMBOL: // Restore x1 from the saved context. ldr x1, [x0, #0xc0] - // TODO(scottmg): save floating-point registers. + // TODO(https://crashpad.chromium.org/bug/300): save floating-point registers. ret diff --git a/util/misc/capture_context_linux.S b/util/misc/capture_context_linux.S index 657a979a..de71e723 100644 --- a/util/misc/capture_context_linux.S +++ b/util/misc/capture_context_linux.S @@ -282,7 +282,7 @@ CAPTURECONTEXT_SYMBOL2: // Restore r1. ldr r1, [r0, #0x24] - // TODO(jperaza): save floating-point registers. + // TODO(https://crashpad.chromium.org/bug/300): save floating-point registers. mov PC, LR @@ -326,7 +326,7 @@ CAPTURECONTEXT_SYMBOL2: // Restore x1 from the saved context. ldr x1, [x0, #0xc0] - // TODO(jperaza): save floating-point registers. + // TODO(https://crashpad.chromium.org/bug/300): save floating-point registers. ret #elif defined(__mips__) diff --git a/util/misc/capture_context_win_arm64.asm b/util/misc/capture_context_win_arm64.asm new file mode 100644 index 00000000..5630698f --- /dev/null +++ b/util/misc/capture_context_win_arm64.asm @@ -0,0 +1,64 @@ +; Copyright 2019 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. + + EXPORT |?CaptureContext@crashpad@@YAXPEAU_CONTEXT@@@Z| + AREA |.text|, CODE +|?CaptureContext@crashpad@@YAXPEAU_CONTEXT@@@Z| PROC + ; Save general purpose registers in context.regs[i]. + ; The original x0 can't be recovered. + stp x0, x1, [x0, #0x008] + stp x2, x3, [x0, #0x018] + stp x4, x5, [x0, #0x028] + stp x6, x7, [x0, #0x038] + stp x8, x9, [x0, #0x048] + stp x10, x11, [x0, #0x058] + stp x12, x13, [x0, #0x068] + stp x14, x15, [x0, #0x078] + stp x16, x17, [x0, #0x088] + stp x18, x19, [x0, #0x098] + stp x20, x21, [x0, #0x0a8] + stp x22, x23, [x0, #0x0b8] + stp x24, x25, [x0, #0x0c8] + stp x26, x27, [x0, #0x0d8] + stp x28, x29, [x0, #0x0e8] + + ; The original LR can't be recovered. + str LR, [x0, #0x0f8] + + ; Use x1 as a scratch register. + mov x1, SP + str x1, [x0, #0x100] ; context.sp + + ; The link register holds the return address for this function. + str LR, [x0, #0x108] ; context.pc + + ; pstate should hold SPSR but NZCV are the only bits we know about. + mrs x1, NZCV + + ; Enable Control flags, such as CONTEXT_ARM64, CONTEXT_CONTROL, + ; CONTEXT_INTEGER + ldr w1, =0x00400003 + + ; Set ControlFlags /0x000/ and pstate /0x004/ at the same time. + str x1, [x0, #0x000] + + ; Restore x1 from the saved context. + ldr x1, [x0, #0x010] + + ; TODO(https://crashpad.chromium.org/bug/300): save floating-point registers + + ret + ENDP + + END diff --git a/util/misc/capture_context_win_arm64.obj b/util/misc/capture_context_win_arm64.obj new file mode 100644 index 00000000..11c76a1a Binary files /dev/null and b/util/misc/capture_context_win_arm64.obj differ