1 /*
2  * Copyright (c) 2024 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #ifndef CODE_SIGN_JIT_FORT_HELPER_H
17 #define CODE_SIGN_JIT_FORT_HELPER_H
18 
19 #include <stdint.h>
20 #include <stdarg.h>
21 #include <sys/syscall.h>
22 #ifdef __aarch64__
23 #include <asm/hwcap.h>
24 #include <cstdio>
25 #endif
26 
27 #include "errcode.h"
28 
29 namespace OHOS {
30 namespace Security {
31 namespace CodeSign {
32 #define JITFORT_PRCTL_OPTION 0x6a6974
33 #define JITFORT_SWITCH_IN   3
34 #define JITFORT_SWITCH_OUT  4
35 #define JITFORT_CPU_FEATURES 7
36 
Syscall(unsigned long n,unsigned long a,unsigned long b,unsigned long c,unsigned long d,unsigned long e)37 __attribute__((always_inline)) static inline long Syscall(
38     unsigned long n, unsigned long a, unsigned long b,
39     unsigned long c, unsigned long d, unsigned long e)
40 {
41 #ifdef __aarch64__
42     register unsigned long x8 __asm__("x8") = n;
43     register unsigned long x0 __asm__("x0") = a;
44     register unsigned long x1 __asm__("x1") = b;
45     register unsigned long x2 __asm__("x2") = c;
46     register unsigned long x3 __asm__("x3") = d;
47     register unsigned long x4 __asm__("x4") = e;
48     asm volatile("svc 0" : "=r"(x0) : "r"(x8), "0"(x0), "r"(x1), \
49         "r"(x2), "r"(x3), "r"(x4) : "memory", "cc");
50     return x0;
51 #else
52     return CS_ERR_UNSUPPORT;
53 #endif
54 }
55 
56 __attribute__((always_inline)) static int inline PrctlWrapper(
57     int op, unsigned long a, unsigned long b = 0)
58 {
59 #ifdef __aarch64__
60     return Syscall(SYS_prctl, op, a, b, 0, 0);
61 #else
62     return CS_ERR_UNSUPPORT;
63 #endif
64 }
65 
IsSupportPACFeature()66 __attribute__((always_inline)) static inline bool IsSupportPACFeature()
67 {
68 #ifdef __aarch64__
69     unsigned long hwcaps = static_cast<unsigned long>(PrctlWrapper(
70         JITFORT_PRCTL_OPTION, JITFORT_CPU_FEATURES, 0));
71     if ((hwcaps & HWCAP_PACA) && (hwcaps & HWCAP_PACG)) {
72         return true;
73     }
74 #endif
75     return false;
76 }
77 }
78 }
79 }
80 #endif