1 /* 2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved. 3 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without modification, 6 * are permitted provided that the following conditions are met: 7 * 8 * 1. Redistributions of source code must retain the above copyright notice, this list of 9 * conditions and the following disclaimer. 10 * 11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list 12 * of conditions and the following disclaimer in the documentation and/or other materials 13 * provided with the distribution. 14 * 15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used 16 * to endorse or promote products derived from this software without specific prior written 17 * permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR 23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; 26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, 27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR 28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF 29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 */ 31 32 #ifndef _LOS_BACKTRACE_H 33 #define _LOS_BACKTRACE_H 34 35 #include "los_config.h" 36 #include "los_arch_interrupt.h" 37 38 #ifdef __cplusplus 39 #if __cplusplus 40 extern "C" { 41 #endif /* __cplusplus */ 42 #endif /* __cplusplus */ 43 44 #define BACKTRACE_MAX_DEPTH LOSCFG_BACKTRACE_DEPTH 45 46 #if (LOSCFG_BACKTRACE_TYPE != 0) 47 #if (LOSCFG_BACKTRACE_TYPE == 1) 48 /* The default name of the code section and CSTACK section are given below, 49 and the user can adjust it according to the linker script file. */ 50 #if defined(__ICCARM__) 51 /* The default code section name is .text */ 52 #define CODE_SECTION_NAME ".text" 53 /* The default C stack section name is CSTACK */ 54 #define CSTACK_SECTION_NAME "CSTACK" 55 #pragma section = CODE_SECTION_NAME 56 #pragma section = CSTACK_SECTION_NAME 57 58 /* Default only one code section. In fact, there may be more than one. 59 You can define more than one and redefine the OsStackDataIsCodeAddr function 60 to support searching in multiple code sections */ 61 #define CODE_START_ADDR ((UINTPTR)__section_begin(CODE_SECTION_NAME)) 62 #define CODE_END_ADDR ((UINTPTR)__section_end(CODE_SECTION_NAME)) 63 #define CSTACK_START_ADDR ((UINTPTR)__section_begin(CSTACK_SECTION_NAME)) 64 #define CSTACK_END_ADDR ((UINTPTR)__section_end(CSTACK_SECTION_NAME)) 65 #elif defined(__CC_ARM) || defined(__CLANG_ARM) 66 /* The default code section name is ER_IROM1 */ 67 #define CODE_SECTION_NAME ER_IROM1 68 /* The default C stack section name is STACK */ 69 #define CSTACK_SECTION_NAME STACK 70 71 #define SECTION_START(_name_) _name_##$$Base 72 #define SECTION_END(_name_) _name_##$$Limit 73 #define CSTACK_SECTION_START(_name_) SECTION_START(_name_) 74 #define CSTACK_SECTION_END(_name_) SECTION_END(_name_) 75 76 #define IMAGE_SECTION_START(_name_) Image$$##_name_##$$Base 77 #define IMAGE_SECTION_END(_name_) Image$$##_name_##$$Limit 78 #define CODE_SECTION_START(_name_) IMAGE_SECTION_START(_name_) 79 #define CODE_SECTION_END(_name_) IMAGE_SECTION_END(_name_) 80 81 extern CHAR *CSTACK_SECTION_START(CSTACK_SECTION_NAME); 82 extern CHAR *CSTACK_SECTION_END(CSTACK_SECTION_NAME); 83 extern CHAR *CODE_SECTION_START(CODE_SECTION_NAME); 84 extern CHAR *CODE_SECTION_END(CODE_SECTION_NAME); 85 86 /* Default only one code section. In fact, there may be more than one. 87 You can define more than one and redefine the OsStackDataIsCodeAddr function 88 to support searching in multiple code sections */ 89 #define CODE_START_ADDR ((UINTPTR)&CODE_SECTION_START(CODE_SECTION_NAME)) 90 #define CODE_END_ADDR ((UINTPTR)&CODE_SECTION_END(CODE_SECTION_NAME)) 91 #define CSTACK_START_ADDR ((UINTPTR)&CSTACK_SECTION_START(CSTACK_SECTION_NAME)) 92 #define CSTACK_END_ADDR ((UINTPTR)&CSTACK_SECTION_END(CSTACK_SECTION_NAME)) 93 #elif defined(__GNUC__) 94 /* The default code section start address */ 95 #define CODE_SECTION_START _stext 96 /* The default code section end address */ 97 #define CODE_SECTION_END _etext 98 /* The default C stack section start address */ 99 #define CSTACK_SECTION_START _sstack 100 /* The default C stack section end address */ 101 #define CSTACK_SECTION_END _estack 102 103 extern CHAR *CODE_SECTION_START; 104 extern CHAR *CODE_SECTION_END; 105 extern CHAR *CSTACK_SECTION_START; 106 extern CHAR *CSTACK_SECTION_END; 107 108 /* Default only one code section. In fact, there may be more than one. 109 You can define more than one and redefine the OsStackDataIsCodeAddr function 110 to support searching in multiple code sections */ 111 #define CODE_START_ADDR ((UINTPTR)&CODE_SECTION_START) 112 #define CODE_END_ADDR ((UINTPTR)&CODE_SECTION_END) 113 #define CSTACK_START_ADDR ((UINTPTR)&CSTACK_SECTION_START) 114 #define CSTACK_END_ADDR ((UINTPTR)&CSTACK_SECTION_END) 115 #else 116 #error Unknown compiler. 117 #endif 118 #elif (LOSCFG_BACKTRACE_TYPE == 2) || (LOSCFG_BACKTRACE_TYPE == 3) 119 #if defined(__GNUC__) 120 /* The default code section start address */ 121 #define CODE_SECTION_START __text_start 122 /* The default code section end address */ 123 #define CODE_SECTION_END __text_end 124 /* The default C stack section start address */ 125 #define CSTACK_SECTION_START __except_stack_top 126 /* The default C stack section end address */ 127 #define CSTACK_SECTION_END __start_and_irq_stack_top 128 129 extern CHAR *CODE_SECTION_START; 130 extern CHAR *CODE_SECTION_END; 131 extern CHAR *CSTACK_SECTION_START; 132 extern CHAR *CSTACK_SECTION_END; 133 134 #define CODE_START_ADDR ((UINTPTR)&CODE_SECTION_START) 135 #define CODE_END_ADDR ((UINTPTR)&CODE_SECTION_END) 136 #define CSTACK_START_ADDR ((UINTPTR)&CSTACK_SECTION_START) 137 #define CSTACK_END_ADDR ((UINTPTR)&CSTACK_SECTION_END) 138 #else 139 #error Unknown compiler. 140 #endif 141 #elif (LOSCFG_BACKTRACE_TYPE == 4) 142 /* The default code section start address */ 143 #define CODE_SECTION_START __text_start 144 /* The default code section end address */ 145 #define CODE_SECTION_END __text_end 146 /* The default C stack section start address */ 147 #define CSTACK_SECTION_START __init_stack_s 148 /* The default C stack section end address */ 149 #define CSTACK_SECTION_END __init_stack_e 150 151 extern CHAR *CODE_SECTION_START; 152 extern CHAR *CODE_SECTION_END; 153 extern CHAR *CSTACK_SECTION_START; 154 extern CHAR *CSTACK_SECTION_END; 155 156 #define CODE_START_ADDR ((UINTPTR)&CODE_SECTION_START) 157 #define CODE_END_ADDR ((UINTPTR)&CODE_SECTION_END) 158 #define CSTACK_START_ADDR ((UINTPTR)&CSTACK_SECTION_START) 159 #define CSTACK_END_ADDR ((UINTPTR)&CSTACK_SECTION_END) 160 161 #define VIR_TEXT_ADDR_MASK 0x80000000 162 #define TEXT_ADDR_MASK 0x40000000 163 #define RA_OFFSET 16 164 #define SP_OFFSET 12 165 #define WINDOW_INCREMENT_SHIFT 2 166 167 UINT32 HalBackTraceGet(UINTPTR sp, UINT32 retAddr, UINTPTR *callChain, UINT32 maxDepth, UINT32 jumpCount); 168 #elif (LOSCFG_BACKTRACE_TYPE == 5) 169 /* The default code section start address */ 170 #define CODE_SECTION_START __text_start 171 /* The default code section end address */ 172 #define CODE_SECTION_END __text_end 173 /* The default C stack section start address */ 174 #define CSTACK_SECTION_START __init_stack_s 175 /* The default C stack section end address */ 176 #define CSTACK_SECTION_END __ram_end 177 178 extern CHAR *CODE_SECTION_START; 179 extern CHAR *CODE_SECTION_END; 180 extern CHAR *CSTACK_SECTION_START; 181 extern CHAR *CSTACK_SECTION_END; 182 183 #define CODE_START_ADDR ((UINTPTR)&CODE_SECTION_START) 184 #define CODE_END_ADDR ((UINTPTR)&CODE_SECTION_END) 185 #define CSTACK_START_ADDR ((UINTPTR)&CSTACK_SECTION_START) 186 #define CSTACK_END_ADDR ((UINTPTR)&CSTACK_SECTION_END) 187 188 #define ALGIN_CODE 2 189 #define STACK_OFFSET 4 190 #elif (LOSCFG_BACKTRACE_TYPE == 6) 191 extern CHAR *__svc_stack; 192 extern CHAR *__svc_stack_top; 193 /* The default code section start address */ 194 #define CODE_SECTION_START __text_start 195 /* The default code section end address */ 196 #define CODE_SECTION_END __text_end 197 /* The default C stack section start address */ 198 #define CSTACK_SECTION_START __svc_stack 199 /* The default C stack section end address */ 200 #define CSTACK_SECTION_END __svc_stack_top 201 202 extern CHAR *CODE_SECTION_START; 203 extern CHAR *CODE_SECTION_END; 204 extern CHAR *CSTACK_SECTION_START; 205 extern CHAR *CSTACK_SECTION_END; 206 207 /* Default only one code section. In fact, there may be more than one. 208 You can define more than one and redefine the OsStackDataIsCodeAddr function 209 to support searching in multiple code sections */ 210 #define CODE_START_ADDR ((UINTPTR)&CODE_SECTION_START) 211 #define CODE_END_ADDR ((UINTPTR)&CODE_SECTION_END) 212 #define CSTACK_START_ADDR ((UINTPTR)&CSTACK_SECTION_START) 213 #define CSTACK_END_ADDR ((UINTPTR)&CSTACK_SECTION_END) 214 215 #endif 216 217 /* This function is currently used to register the memory leak check hook, 218 other uses do not need to be called temporarily. */ 219 VOID OsBackTraceInit(VOID); 220 221 /* This function is used to print the function call stack. */ 222 VOID LOS_BackTrace(VOID); 223 224 /* This function is used to record the function call stack. */ 225 VOID LOS_RecordLR(UINTPTR *LR, UINT32 LRSize, UINT32 jumpCount, UINTPTR SP); 226 #endif 227 228 #ifdef __cplusplus 229 #if __cplusplus 230 } 231 #endif /* __cplusplus */ 232 #endif /* __cplusplus */ 233 #endif 234 235