1/*
2 * Copyright (c) Huawei Technologies Co., Ltd. 2021. All rights reserved.
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 HOOK_COMMON_H
17#define HOOK_COMMON_H
18
19#if defined(HAVE_LIBUNWIND) && HAVE_LIBUNWIND
20// for libunwind.h empty struct has size 0 in c, size 1 in c++
21#define UNW_EMPTY_STRUCT uint8_t unused;
22#include <libunwind.h>
23#endif
24
25#include "register.h"
26#include "utilities.h"
27
28#define MAX_THREAD_NAME (32)
29#define MAX_UNWIND_DEPTH (100)
30
31namespace OHOS {
32namespace Developtools {
33namespace NativeDaemon {
34const int STACK_DATA_SIZE = 40000;
35const int SPEED_UP_THRESHOLD = STACK_DATA_SIZE / 2;
36const int SLOW_DOWN_THRESHOLD = STACK_DATA_SIZE / 4;
37const int32_t MIN_STACK_DEPTH = 6;
38// filter two layers of dwarf stack in libnative_hook.z.so
39const size_t FILTER_STACK_DEPTH = 2;
40const size_t MAX_CALL_FRAME_UNWIND_SIZE = MAX_UNWIND_DEPTH + FILTER_STACK_DEPTH;
41// dlopen function minimum stack depth
42const int32_t DLOPEN_MIN_UNWIND_DEPTH = 5;
43const uint32_t  MMAP_FILE_TYPE = (1u << 8);
44// default max js stack depth
45const int32_t DEFAULT_MAX_JS_STACK_DEPTH = 10;
46}
47}
48}
49
50constexpr size_t MAX_REG_SIZE = sizeof(uint64_t)
51    * OHOS::Developtools::NativeDaemon::PERF_REG_ARM64_MAX;
52
53enum {
54    MALLOCDISABLE = (1u << 0),
55    MMAPDISABLE = (1u << 1),
56    FREEMSGSTACK = (1u << 2),
57    MUNMAPMSGSTACK = (1u << 3),
58    FPUNWIND = (1u << 4),
59    BLOCKED = (1u << 5),
60    MEMTRACE_ENABLE = (1u << 6),
61};
62
63enum {
64    MALLOC_MSG = 0,
65    FREE_MSG,
66    MMAP_MSG,
67    MMAP_FILE_PAGE_MSG,
68    MUNMAP_MSG,
69    MEMORY_USING_MSG,
70    MEMORY_UNUSING_MSG,
71    MEMORY_TAG,
72    THREAD_NAME_MSG,
73    PR_SET_VMA_MSG,
74    JS_STACK_MSG,
75    NMD_MSG,
76    END_MSG,
77};
78
79struct alignas(8) MmapFileRawData { // 8 is 8 bit
80    off_t offset;
81    uint32_t flags;
82};
83
84struct alignas(8) BaseStackRawData { // 8 is 8 bit
85    union {
86        struct timespec ts;
87        MmapFileRawData mmapArgs;
88    };
89    void* addr;
90    size_t mallocSize;
91    uint64_t jsChainId;
92    uint32_t pid;
93    uint32_t tid;
94    uint16_t type;
95    uint16_t tagId;
96};
97
98struct alignas(8) StackRawData: public BaseStackRawData { // 8 is 8 bit
99    union {
100        char regs[MAX_REG_SIZE];
101        uint64_t ip[MAX_UNWIND_DEPTH];
102        char name[PATH_MAX + 1] {0};
103    };
104};
105
106struct alignas(8) ReportEventBaseData { // 8 is 8 bit
107    ReportEventBaseData(const BaseStackRawData* baseData, uint32_t id = 0)
108    {
109        ts = baseData->ts;
110        addr = reinterpret_cast<uint64_t>(baseData->addr);
111        type = baseData->type;
112        tagId = baseData->tagId;
113        mallocSize = baseData->mallocSize;
114        tid = baseData->tid;
115        stackMapId = id;
116    }
117    struct timespec ts;
118    uint64_t addr : 40;
119    uint64_t type : 8;
120    uint64_t tagId : 16;
121    uint32_t mallocSize;
122    uint32_t tid;
123    uint32_t stackMapId;
124};
125
126struct alignas(8) ArkTsClientConfig { // 8 is 8 bit
127        int32_t jsStackReport = 0;
128        uint8_t maxJsStackDepth = 0;
129        bool jsFpunwind = false;
130        char filterNapiName[64] = {""};
131};
132
133struct alignas(8) ClientConfig { // 8 is 8 bit
134    void Reset()
135    {
136        filterSize = -1;
137        shareMemorySize = 0;
138        clockId = CLOCK_REALTIME;
139        maxStackDepth = 0;
140        statisticsInterval = 0;
141        sampleInterval = 0;
142        mallocDisable = false;
143        mmapDisable = false;
144        freeStackData = false;
145        munmapStackData = false;
146        fpunwind = false;
147        isBlocked = false;
148        memtraceEnable = false;
149        responseLibraryMode = false;
150        freeEventOnlyAddrEnable = false;
151        printNmd = false;
152        nmdType = -1;
153        arktsConfig.jsStackReport = 0;
154        arktsConfig.maxJsStackDepth = 0;
155        arktsConfig.jsFpunwind = false;
156        arktsConfig.filterNapiName[0] = '\0';
157    }
158
159    std::string ToString()
160    {
161        std::stringstream ss;
162        ss << "filterSize:" << filterSize << ", shareMemorySize:" << shareMemorySize
163            << ", clockId:" << clockId << ", maxStackDepth:" << std::to_string(maxStackDepth)
164            << ", mallocDisable:" << mallocDisable << ", mmapDisable:" << mmapDisable
165            << ", freeStackData:" << freeStackData << ", munmapStackData:" << munmapStackData
166            << ", fpunwind:" << fpunwind << ", isBlocked:" << isBlocked << ", memtraceEnable:" << memtraceEnable
167            << ", sampleInterval: " << sampleInterval << ", responseLibraryMode: " << responseLibraryMode
168            << ", freeEventOnlyAddrEnable: " << freeEventOnlyAddrEnable << ", jsStackReport: "
169            << arktsConfig.jsStackReport << ", maxJsStackDepth: "
170            << std::to_string(arktsConfig.maxJsStackDepth) << ", filterNapiName: "
171            << arktsConfig.filterNapiName << ", jsFpunwind: " << arktsConfig.jsFpunwind;
172        return ss.str();
173    }
174
175    int32_t filterSize = -1;
176    uint32_t shareMemorySize = 0;
177    uint32_t sampleInterval = 0;
178    uint32_t statisticsInterval = 0;
179    clockid_t clockId = CLOCK_REALTIME;
180    uint8_t maxStackDepth = 0;
181    bool mallocDisable = false;
182    bool mmapDisable = false;
183    bool freeStackData = false;
184    bool munmapStackData = false;
185    bool fpunwind = false;
186    bool isBlocked = false;
187    bool memtraceEnable = false;
188    bool responseLibraryMode = false;
189    bool freeEventOnlyAddrEnable = false;
190    bool printNmd = false;
191    int nmdType = -1;
192    ArkTsClientConfig arktsConfig = {0};
193};
194#endif // HOOK_COMMON_H