Line data Source code
1 : /**
2 : * Copyright (c) 2025 Huawei Technologies Co., Ltd.
3 : * This program is free software, you can redistribute it and/or modify it under the terms and conditions of
4 : * CANN Open Software License Agreement Version 2.0 (the "License").
5 : * Please refer to the License for details. You may not use this file except in compliance with the License.
6 : * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED,
7 : * INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY, OR FITNESS FOR A PARTICULAR PURPOSE.
8 : * See LICENSE in the root of the software repository for the full text of the License.
9 : */
10 :
11 : #ifndef STACKCORE_UNWIND_INNER_H
12 : #define STACKCORE_UNWIND_INNER_H
13 :
14 : #include <stddef.h>
15 : #include "atrace_types.h"
16 : #include "securec.h"
17 : #include "stacktrace_logger.h"
18 : #include "scd_dwarf.h"
19 : #include "scd_log.h"
20 :
21 : #ifdef __cplusplus
22 : extern "C" {
23 : #endif // __cplusplus
24 :
25 :
26 : #define DW_EH_PE_OMIT 0xffU /* The value is not present */
27 : /* 判断eh_frame_hdr段中是否有搜索表 */
28 : #define TRACE_IS_HDR_TBL_PRESENT(frameHdrInfo) \
29 : (((DW_EH_PE_OMIT != (frameHdrInfo)->tabEnc) && \
30 : (DW_EH_PE_OMIT != (frameHdrInfo)->fdeCountEnc)) && \
31 : ((DW_EH_PE_DATAREL | DW_EH_PE_DATA4) == (frameHdrInfo)->tabEnc))
32 :
33 : /* 解析过程中地址非法 */
34 : #define TRACE_UNWIND_PARSE_ADDR_CHECK_OR_RETURN(addr) \
35 : do { \
36 : if ((addr) == NULL) { \
37 : return NULL; \
38 : } \
39 : } while (0)
40 :
41 : #define TRACE_STACK_INDEX_CHECK_RET(idx, uiExpect, ret) \
42 : do { \
43 : if ((uiExpect) > (idx)) { \
44 : ret \
45 : } \
46 : } while (0)
47 :
48 : #if defined(TRACE_WORDSIZE) && (TRACE_WORDSIZE != 64)
49 : #define TRACE_MAX_LEB_BYRE 0x05 /* 该CPU环境下表示长整形所用uleb/sleb类型表示最大字节数 */
50 : #else
51 : #define TRACE_MAX_LEB_BYRE 0x0a /* 该CPU环境下表示长整形所用uleb/sleb类型表示最大字节数 */
52 : #endif
53 :
54 : #define TRACE_GET_LOW_BIT_VALUE 0x7fU
55 : #define TRACE_GET_HIG_BIT_VALUE 0x80U
56 : #define TRACE_MOVE_BIT_COUNT 0x07U
57 :
58 : /* 高字节对齐 */
59 : #define TRACE_UNWIND_HALIGN(value) ((((value) + sizeof(size_t) - 1U)) & ~((size_t)sizeof(size_t) - 1U))
60 :
61 : /* 字节低位设置为0 */
62 : #define TRACE_LOW_BIT_ZERO(data) (~((size_t)(data) - 1U))
63 :
64 : /* the parse of the encode type */
65 : #define TRACE_HIBIT1_ENCODE(x) ((x) & 0x80U)
66 : #define TRACE_MDBIT3_ENCODE(x) ((x) & 0x70U)
67 : #define TRACE_LOBIT4_ENCODE(x) ((x) & 0x0fU)
68 :
69 :
70 : /* DWARF Exception Header Encoding:used to describe the type
71 : * data about two unwind segment:.eh_frame_hdr and .eh_frame.
72 : * Use one byte: the upper 4 bits and lower 4 bits different.
73 : */
74 : #define DW_EH_PE_ABSPTR 0x00U /* The type of pointer relative to architecture or address space */
75 : #define DW_EH_PE_ULEB128 0x01U /* Unsigned little endian base 128 */
76 : #define DW_EH_PE_UDATA2 0x02U /* Unsigned 2 Byte */
77 : #define DW_EH_PE_UDATA4 0x03U /* Unsigned 4 Byte */
78 : #define DW_EH_PE_UDATA8 0x04U /* Unsigned 8 Byte */
79 : #define DW_EH_PE_SIGNED 0x08U /* signed number relative to architecture or address space */
80 : #define DW_EH_PE_SLEB128 0x09U /* signed little endian base 128 */
81 : #define DW_EH_PE_DATA2 0x0aU /* signed 2 Byte */
82 : #define DW_EH_PE_DATA4 0x0bU /* signed 4 Byte */
83 : #define DW_EH_PE_DATA8 0x0cU /* signed 8 Byte */
84 :
85 : #define DW_EH_PE_PCREL 0X10U /* The value is relative to PC */
86 : #define DW_EH_PE_TEXTREL 0x20U /* The value is relative to Text */
87 : #define DW_EH_PE_DATAREL 0x30U /* The value is relative to Data */
88 : #define DW_EH_PE_FUNCREL 0x40U /* The value is relative to function start */
89 : #define DW_EH_PE_ALIGNED 0x50U /* The value is relative to the alignment of address */
90 : #define DW_EH_PE_INDIRECT 0x80U /* The address of the real value */
91 :
92 : const uint8_t *TraceReadEncodeValue(ScdDwarf *dwarf, const uint8_t encode, const uint8_t *byteAddr, uintptr_t *val);
93 : const uint8_t *TraceReadUleb128(ScdDwarf *dwarf, const uint8_t *byteStream, uintptr_t *val);
94 : const uint8_t *TraceReadLeb128(ScdDwarf *dwarf, const uint8_t *byteStream, intptr_t *psvVal);
95 : size_t TraceReadBytes(ScdDwarf *dwarf, const uint8_t **src, void *dst, size_t size);
96 : size_t TraceEncValueSizeGet(uint8_t encode);
97 16 : static inline uint64_t TraceReadU64(const uint8_t *addr, size_t size)
98 : {
99 16 : uint64_t result = 0;
100 16 : errno_t ret = memcpy_s(&result, sizeof(result), (const void *)addr, size);
101 16 : if (ret != EOK) {
102 0 : SCD_DLOG_ERR("memcpy addr to uint64_t failed, ret : %d", ret);
103 0 : return 0;
104 : }
105 16 : return result;
106 : }
107 16 : static inline int64_t TraceReadS64(const uint8_t *addr, size_t size)
108 : {
109 16 : int64_t result = 0;
110 16 : errno_t ret = memcpy_s(&result, sizeof(result), (const void *)addr, size);
111 16 : if (ret != EOK) {
112 0 : SCD_DLOG_ERR("memcpy addr to int64_t failed, ret : %d", ret);
113 0 : return 0;
114 : }
115 16 : return result;
116 : }
117 32 : static inline uint32_t TraceReadU32(const uint8_t *addr, size_t size)
118 : {
119 32 : uint32_t result = 0;
120 32 : errno_t ret = memcpy_s(&result, sizeof(result), (const void *)addr, size);
121 32 : if (ret != EOK) {
122 0 : SCD_DLOG_ERR("memcpy addr to uint32_t failed, ret : %d", ret);
123 0 : return 0;
124 : }
125 32 : return result;
126 : }
127 16 : static inline int32_t TraceReadS32(const uint8_t *addr, size_t size)
128 : {
129 16 : int32_t result = 0;
130 16 : errno_t ret = memcpy_s(&result, sizeof(result), (const void *)addr, size);
131 16 : if (ret != EOK) {
132 0 : SCD_DLOG_ERR("memcpy addr to int32_t failed, ret : %d", ret);
133 0 : return 0;
134 : }
135 16 : return result;
136 : }
137 16 : static inline int16_t TraceReadS16(const uint8_t *addr, size_t size)
138 : {
139 16 : int16_t result = 0;
140 16 : errno_t ret = memcpy_s(&result, sizeof(result), (const void *)addr, size);
141 16 : if (ret != EOK) {
142 0 : SCD_DLOG_ERR("memcpy addr to int16_t failed, ret : %d", ret);
143 0 : return 0;
144 : }
145 16 : return result;
146 : }
147 64 : static inline uint16_t TraceReadU16(const uint8_t *addr, size_t size)
148 : {
149 64 : uint16_t result = 0;
150 64 : errno_t ret = memcpy_s(&result, sizeof(result), (const void *)addr, size);
151 64 : if (ret != EOK) {
152 0 : SCD_DLOG_ERR("memcpy addr to uint16_t failed, ret : %d", ret);
153 0 : return 0;
154 : }
155 64 : return result;
156 : }
157 16 : static inline uintptr_t TraceReadUintptr(const uint8_t *addr, size_t size)
158 : {
159 16 : uintptr_t result = 0;
160 16 : errno_t ret = memcpy_s(&result, sizeof(result), addr, size);
161 16 : if (ret != EOK) {
162 0 : SCD_DLOG_ERR("memcpy addr to uintptr_t failed, ret : %d", ret);
163 0 : return 0;
164 : }
165 16 : return result;
166 : }
167 : #ifdef __cplusplus
168 : }
169 : #endif // __cplusplus
170 : #endif
171 :
|