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 : #define DW_EH_PE_OMIT 0xffU /* The value is not present */
26 : /* 判断eh_frame_hdr段中是否有搜索表 */
27 : #define TRACE_IS_HDR_TBL_PRESENT(frameHdrInfo) \
28 : (((DW_EH_PE_OMIT != (frameHdrInfo)->tabEnc) && (DW_EH_PE_OMIT != (frameHdrInfo)->fdeCountEnc)) && \
29 : ((DW_EH_PE_DATAREL | DW_EH_PE_DATA4) == (frameHdrInfo)->tabEnc))
30 :
31 : /* 解析过程中地址非法 */
32 : #define TRACE_UNWIND_PARSE_ADDR_CHECK_OR_RETURN(addr) \
33 : do { \
34 : if ((addr) == NULL) { \
35 : return NULL; \
36 : } \
37 : } while (0)
38 :
39 : #define TRACE_STACK_INDEX_CHECK_RET(idx, uiExpect, ret) \
40 : do { \
41 : if ((uiExpect) > (idx)) { \
42 : ret \
43 : } \
44 : } while (0)
45 :
46 : #if defined(TRACE_WORDSIZE) && (TRACE_WORDSIZE != 64)
47 : #define TRACE_MAX_LEB_BYRE 0x05 /* 该CPU环境下表示长整形所用uleb/sleb类型表示最大字节数 */
48 : #else
49 : #define TRACE_MAX_LEB_BYRE 0x0a /* 该CPU环境下表示长整形所用uleb/sleb类型表示最大字节数 */
50 : #endif
51 :
52 : #define TRACE_GET_LOW_BIT_VALUE 0x7fU
53 : #define TRACE_GET_HIG_BIT_VALUE 0x80U
54 : #define TRACE_MOVE_BIT_COUNT 0x07U
55 :
56 : /* 高字节对齐 */
57 : #define TRACE_UNWIND_HALIGN(value) ((((value) + sizeof(size_t) - 1U)) & ~((size_t)sizeof(size_t) - 1U))
58 :
59 : /* 字节低位设置为0 */
60 : #define TRACE_LOW_BIT_ZERO(data) (~((size_t)(data)-1U))
61 :
62 : /* the parse of the encode type */
63 : #define TRACE_HIBIT1_ENCODE(x) ((x)&0x80U)
64 : #define TRACE_MDBIT3_ENCODE(x) ((x)&0x70U)
65 : #define TRACE_LOBIT4_ENCODE(x) ((x)&0x0fU)
66 :
67 : /* DWARF Exception Header Encoding:used to describe the type
68 : * data about two unwind segment:.eh_frame_hdr and .eh_frame.
69 : * Use one byte: the upper 4 bits and lower 4 bits different.
70 : */
71 : #define DW_EH_PE_ABSPTR 0x00U /* The type of pointer relative to architecture or address space */
72 : #define DW_EH_PE_ULEB128 0x01U /* Unsigned little endian base 128 */
73 : #define DW_EH_PE_UDATA2 0x02U /* Unsigned 2 Byte */
74 : #define DW_EH_PE_UDATA4 0x03U /* Unsigned 4 Byte */
75 : #define DW_EH_PE_UDATA8 0x04U /* Unsigned 8 Byte */
76 : #define DW_EH_PE_SIGNED 0x08U /* signed number relative to architecture or address space */
77 : #define DW_EH_PE_SLEB128 0x09U /* signed little endian base 128 */
78 : #define DW_EH_PE_DATA2 0x0aU /* signed 2 Byte */
79 : #define DW_EH_PE_DATA4 0x0bU /* signed 4 Byte */
80 : #define DW_EH_PE_DATA8 0x0cU /* signed 8 Byte */
81 :
82 : #define DW_EH_PE_PCREL 0X10U /* The value is relative to PC */
83 : #define DW_EH_PE_TEXTREL 0x20U /* The value is relative to Text */
84 : #define DW_EH_PE_DATAREL 0x30U /* The value is relative to Data */
85 : #define DW_EH_PE_FUNCREL 0x40U /* The value is relative to function start */
86 : #define DW_EH_PE_ALIGNED 0x50U /* The value is relative to the alignment of address */
87 : #define DW_EH_PE_INDIRECT 0x80U /* The address of the real value */
88 :
89 : const uint8_t* TraceReadEncodeValue(ScdDwarf* dwarf, const uint8_t encode, const uint8_t* byteAddr, uintptr_t* val);
90 : const uint8_t* TraceReadUleb128(ScdDwarf* dwarf, const uint8_t* byteStream, uintptr_t* val);
91 : const uint8_t* TraceReadLeb128(ScdDwarf* dwarf, const uint8_t* byteStream, intptr_t* psvVal);
92 : size_t TraceReadBytes(ScdDwarf* dwarf, const uint8_t** src, void* dst, size_t size);
93 : size_t TraceEncValueSizeGet(uint8_t encode);
94 18 : static inline uint64_t TraceReadU64(const uint8_t* addr, size_t size)
95 : {
96 18 : uint64_t result = 0;
97 18 : errno_t ret = memcpy_s(&result, sizeof(result), (const void*)addr, size);
98 18 : if (ret != EOK) {
99 0 : SCD_DLOG_ERR("memcpy addr to uint64_t failed, ret : %d", ret);
100 0 : return 0;
101 : }
102 18 : return result;
103 : }
104 18 : static inline int64_t TraceReadS64(const uint8_t* addr, size_t size)
105 : {
106 18 : int64_t result = 0;
107 18 : errno_t ret = memcpy_s(&result, sizeof(result), (const void*)addr, size);
108 18 : if (ret != EOK) {
109 0 : SCD_DLOG_ERR("memcpy addr to int64_t failed, ret : %d", ret);
110 0 : return 0;
111 : }
112 18 : return result;
113 : }
114 36 : static inline uint32_t TraceReadU32(const uint8_t* addr, size_t size)
115 : {
116 36 : uint32_t result = 0;
117 36 : errno_t ret = memcpy_s(&result, sizeof(result), (const void*)addr, size);
118 36 : if (ret != EOK) {
119 0 : SCD_DLOG_ERR("memcpy addr to uint32_t failed, ret : %d", ret);
120 0 : return 0;
121 : }
122 36 : return result;
123 : }
124 18 : static inline int32_t TraceReadS32(const uint8_t* addr, size_t size)
125 : {
126 18 : int32_t result = 0;
127 18 : errno_t ret = memcpy_s(&result, sizeof(result), (const void*)addr, size);
128 18 : if (ret != EOK) {
129 0 : SCD_DLOG_ERR("memcpy addr to int32_t failed, ret : %d", ret);
130 0 : return 0;
131 : }
132 18 : return result;
133 : }
134 18 : static inline int16_t TraceReadS16(const uint8_t* addr, size_t size)
135 : {
136 18 : int16_t result = 0;
137 18 : errno_t ret = memcpy_s(&result, sizeof(result), (const void*)addr, size);
138 18 : if (ret != EOK) {
139 0 : SCD_DLOG_ERR("memcpy addr to int16_t failed, ret : %d", ret);
140 0 : return 0;
141 : }
142 18 : return result;
143 : }
144 72 : static inline uint16_t TraceReadU16(const uint8_t* addr, size_t size)
145 : {
146 72 : uint16_t result = 0;
147 72 : errno_t ret = memcpy_s(&result, sizeof(result), (const void*)addr, size);
148 72 : if (ret != EOK) {
149 0 : SCD_DLOG_ERR("memcpy addr to uint16_t failed, ret : %d", ret);
150 0 : return 0;
151 : }
152 72 : return result;
153 : }
154 18 : static inline uintptr_t TraceReadUintptr(const uint8_t* addr, size_t size)
155 : {
156 18 : uintptr_t result = 0;
157 18 : errno_t ret = memcpy_s(&result, sizeof(result), addr, size);
158 18 : if (ret != EOK) {
159 0 : SCD_DLOG_ERR("memcpy addr to uintptr_t failed, ret : %d", ret);
160 0 : return 0;
161 : }
162 18 : return result;
163 : }
164 : #ifdef __cplusplus
165 : }
166 : #endif // __cplusplus
167 : #endif
|