1/*
2 * Copyright (C) 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17/*
18 * Clang instruments HWASan-enabled code with __hwasan_check_* functions. If a
19 * tag mismatch is detected, __hwasan_check_* calls into __hwasan_tag_mismatch
20 * with a custom calling convention.
21 *
22 * __hwasan_check_* sets up the stack frame for __hwasan_tag_mismatch, saves x0,
23 * x1, x29, and x30, then branches into __hwasan_tag_mismatch. Here is an
24 * example:
25 *    stp x0, x1, [sp,#-256]!
26 *    stp x29, x30, [sp,#232]
27 *    mov x0, <fault address>
28 *    mov x1, <custom argument>
29 *    b <address of __hwasan_tag_mismatch>
30 *
31 * __hwasan_check_* and __hwasan_tag_mismatch effectively share the stack frame.
32 * __hwasan_tag_mismatch is expected to save the rest of the registers and do
33 * error reporting. In our case, it calls into __hwasan_report_error, which is a
34 * C function, using C calling convention.
35 *
36 * __hwasan_tag_mismatch is not expected to return. However, for testing
37 * purposes, we report the error, restore the registers, then return to the
38 * caller of __hwasan_check_*, and just continue execution.
39 */
40
41#include <arch/asm.h>
42
43.section .text
44.file "hwasan_tag_mismatch.S"
45.global __hwasan_tag_mismatch;
46.type __hwasan_tag_mismatch,STT_FUNC;
47__hwasan_tag_mismatch:
48	bti c
49	str x28,      [sp, #224]
50	stp x26, x27, [sp, #208]
51	stp x24, x25, [sp, #192]
52	stp x22, x23, [sp, #176]
53	stp x20, x21, [sp, #160]
54	stp x18, x19, [sp, #144]
55	stp x16, x17, [sp, #128]
56	stp x14, x15, [sp, #112]
57	stp x12, x13, [sp, #96]
58	stp x10, x11, [sp, #80]
59	stp x8,  x9,  [sp, #64]
60	stp x6,  x7,  [sp, #48]
61	stp x4,  x5,  [sp, #32]
62	stp x2,  x3,  [sp, #16]
63
64	/*
65	 * Frame is allocated by the caller of __hwasan_tag_mismatch(). Adjust frame
66	 * pointer to correct spot.
67	 */
68	add fp, sp, #232
69
70	mov x1, sp
71	bl __hwasan_report_error
72
73	/*
74	 * HACK: this function must not return, but we do this for bring up and
75	 * testing
76	 */
77	ldr x28,      [sp, #224]
78	ldp x26, x27, [sp, #208]
79	ldp x24, x25, [sp, #192]
80	ldp x22, x23, [sp, #176]
81	ldp x20, x21, [sp, #160]
82	ldp x18, x19, [sp, #144]
83	ldp x16, x17, [sp, #128]
84	ldp x14, x15, [sp, #112]
85	ldp x12, x13, [sp, #96]
86	ldp x10, x11, [sp, #80]
87	ldp x8,  x9,  [sp, #64]
88	ldp x6,  x7,  [sp, #48]
89	ldp x4,  x5,  [sp, #32]
90	ldp x2,  x3,  [sp, #16]
91
92	ldp x0,  x1,  [sp]
93	ldp x29, x30, [sp, #232]
94	add sp, sp, #256
95	ret
96
97SECTION_GNU_NOTE_PROPERTY_AARCH64_FEATURES(GNU_NOTE_FEATURE_AARCH64_BTI)
98