![]() |
SyterKit 0.4.0.x
SyterKit is a bare-metal framework
|
#include <io.h>#include <stdarg.h>#include <stdbool.h>#include <stddef.h>#include <stdint.h>#include <stdlib.h>#include <types.h>#include <timer.h>#include <log.h>
Macros | |
| #define | BT_SCAN_MAX_LIMIT 0xFFFFFF |
| Maximum limit for backtrace scanning. | |
| #define | BT_LEVEL_LIMIT 64 |
| Maximum number of backtrace levels. | |
| #define | PC2ADDR(pc) ((char *) (((uint32_t) (pc)) & 0xfffffffe)) |
| Converts a program counter (PC) value to an address. | |
| #define | insn_length(x) |
| Determines the length of an instruction in bytes based on its encoding. | |
| #define | BITS(x, high, low) ((x) & (((1 << ((high) - (low) + 1)) - 1) << (low))) |
| Extracts a specific bit field from a value. | |
| #define | ARM_STATE 0 |
| ARM state macro definition. | |
| #define | THUMB_STATE 1 |
| THUMB state macro definition. | |
| #define | IS_THUMB_ADDR(pc) ((uint32_t) (pc) &0x1) |
| Macro to check if the program counter (PC) is in THUMB mode. | |
Functions | |
| static int | backtrace_check_address (void *pc) |
| Checks whether a given program counter (PC) address is within a valid range. | |
| static int | thumb_thumb32bit_code (uint16_t ic) |
| Checks if a given Thumb instruction is a 32-bit Thumb instruction. | |
| static int | find_lr_offset (char *LR, bool *state) |
| Finds the offset for the Link Register (LR) based on the processor state. | |
| static int | thumb_get_next_inst (int *error, int *offset, char *ins16_h_addr, char *ins16_l_addr, int lsb, int *thumb32bit) |
| Retrieves the next Thumb instruction from the given addresses. | |
| static int | thumb_get_push_lr_ins_framesize (uint32_t inst, int *offset, int thumb32bit) |
Calculates the frame size for a push or store-multiple instruction that includes the link register (lr). | |
| static int | thumb_backtrace_stack_push (uint32_t inst, int thumb32bit) |
| Calculate the frame size based on the instruction and determine the stack adjustment. | |
| static int | thumb_backtrace_from_stack (int **pSP, char **pPC, char **pLR) |
| Perform a backtrace from the stack and retrieve the next return address and program counter (PC). | |
| static int | arm_get_push_lr_ins_framesize (uint32_t inst, int *offset) |
| Analyzes an ARM instruction to determine the frame size and the offset for the link register (LR). | |
| static int | arm_backtrace_stack_push (uint32_t inst) |
| Analyzes an ARM instruction to determine the frame size for stack operations. | |
| static int | arm_bakctrace_from_stack (int **pSP, char **pPC, char **pLR) |
| Performs backtrace from the stack to find the return address and program counter. | |
| static int | backtrace_from_stack (int **pSP, char **pPC, char **pLR) |
| Backtrace from stack based on program counter (PC) state. | |
| static int | thumb_backtrace_stack_pop (uint32_t inst, uint8_t *sp_change, int thumb32bit) |
| Pop a frame from the stack for Thumb instructions. | |
| static int | thumb_backtrace_return_pop (uint32_t inst, int thumb32bit) |
| Process the return instruction for Thumb mode and determine the frame size. | |
| static int | thumb_get_push_ins_framesize (uint32_t inst, uint8_t *jump, int thumb32bit) |
| Calculate the frame size for a "push" instruction in Thumb mode. | |
| static int | thumb_backtrace_from_lr (int **pSP, char **pPC, char *LR) |
| Perform a backtrace from the Link Register (LR) in Thumb mode. | |
| static int | arm_backtrace_return_pop (uint32_t inst) |
| Analyze the ARM instruction to determine the frame size for backtrace. | |
| static int | arm_backtrace_stack_pop (uint32_t inst) |
| Analyze the ARM instruction to determine the frame size for stack pop operations. | |
| static int | arm_backtrace_from_lr (int **pSP, char **pPC, char *LR) |
| Perform backtrace from the link register (LR) to determine the stack pointer (SP) and program counter (PC). | |
| static int | backtrace_from_lr (int **pSP, char **pPC, char *LR) |
| Perform a backtrace from the Link Register (LR). | |
| int | backtrace (char *PC, long *SP, char *LR) |
| Perform a backtrace to find the call stack. | |
| int | dump_stack (void) |
| Dumps the current stack state and performs a backtrace. | |
Variables | |
| uint8_t | __spl_start [] |
| Pointer to the start of the image in memory. | |
| uint8_t | __stack_srv_end [] |
| Pointer to the end of the stack service region. | |
| #define ARM_STATE 0 |
ARM state macro definition.
This macro represents the ARM state in ARM architecture.
| #define BITS | ( | x, | |
| high, | |||
| low | |||
| ) | ((x) & (((1 << ((high) - (low) + 1)) - 1) << (low))) |
Extracts a specific bit field from a value.
This macro extracts a bit field from a value x based on the specified high and low bit positions. The bits are masked and shifted to the right, leaving the desired bit field.
| x | The value from which to extract the bit field. |
| high | The index of the highest bit (inclusive). |
| low | The index of the lowest bit (inclusive). |
| #define BT_LEVEL_LIMIT 64 |
Maximum number of backtrace levels.
This constant defines the maximum depth of the backtrace. It limits how many stack frames the backtrace function can unwind before stopping.
| #define BT_SCAN_MAX_LIMIT 0xFFFFFF |
Maximum limit for backtrace scanning.
This constant defines the maximum limit for scanning the backtrace. The backtrace function will scan instructions and stack frames up to this size. If the limit is exceeded, the backtrace operation will fail.
| #define insn_length | ( | x | ) |
Determines the length of an instruction in bytes based on its encoding.
This macro computes the length of an instruction in bytes, given a 32-bit instruction encoding. The length is determined based on specific bit patterns in the instruction word.
| x | The instruction encoding (32-bit). |
| #define IS_THUMB_ADDR | ( | pc | ) | ((uint32_t) (pc) &0x1) |
Macro to check if the program counter (PC) is in THUMB mode.
This macro checks whether the given program counter address (PC) points to the THUMB mode. According to ARM architecture, if the least significant bit (LSB) of the program counter (PC) is 1, the instruction set is in THUMB mode.
| pc | The program counter (typically the address of an instruction) |
| #define PC2ADDR | ( | pc | ) | ((char *) (((uint32_t) (pc)) & 0xfffffffe)) |
Converts a program counter (PC) value to an address.
This macro takes a program counter (PC) value and converts it to a valid address by clearing the least significant bit. This operation is commonly used to align PC addresses properly for instruction fetch.
| pc | The program counter value to convert. |
| #define THUMB_STATE 1 |
THUMB state macro definition.
This macro represents the THUMB state in ARM architecture.
|
static |
Perform backtrace from the link register (LR) to determine the stack pointer (SP) and program counter (PC).
This function performs a backtrace from the provided LR (link register) to locate the stack pointer and program counter of the current function. It checks the validity of addresses, scans instructions to compute the stack frame size, and adjusts the program counter based on the ARM instruction set state (ARM or Thumb).
| pSP | A pointer to the stack pointer (SP) to be updated. |
| pPC | A pointer to the program counter (PC) to be updated. |
| LR | The link register value from which the backtrace will begin. |
|
static |
Analyze the ARM instruction to determine the frame size for backtrace.
This function interprets an ARM instruction and determines the frame size based on the instruction type. It handles the following instructions:
pop {..., pc}: Pops the program counter (pc) from the stack.bx lr: Branches to the link register (lr), effectively returning from a function.ldr pc, [sp], #4: Loads the program counter (pc) from the stack and updates the stack pointer.| inst | The ARM instruction to analyze. |
|
static |
Analyze the ARM instruction to determine the frame size for stack pop operations.
This function interprets an ARM instruction and determines the frame size based on the instruction type. It handles the following instructions:
add sp, sp, #imm: Adds an immediate value to the stack pointer (sp).pop {...}: Pops a set of registers from the stack.vpop {...}: Pops a set of vector registers from the stack.ldr xxx, [sp], #4: Loads a value from the stack into a register and updates the stack pointer.| inst | The ARM instruction to analyze. |
|
static |
Analyzes an ARM instruction to determine the frame size for stack operations.
This function inspects the provided ARM instruction to determine the size of the stack frame based on common instructions such as sub sp, sp, #imm, push, vpush, and str xxx, [sp, #-4]!. It returns the size of the stack frame in terms of the number of words (4-byte units) affected by the instruction.
| inst | The ARM instruction to be analyzed (32-bit uint32_teger). |
|
static |
Performs backtrace from the stack to find the return address and program counter.
This function attempts to deduce the return address (LR) and program counter (PC) by analyzing the stack and the instructions around it. It parses the stack to find the correct frame size, validates the text addresses, and adjusts the program counter based on the instruction state (ARM/Thumb).
| pSP | Pointer to the current stack pointer (SP). |
| pPC | Pointer to the current program counter (PC). |
| pLR | Pointer to the link register (LR). |
|
static |
Analyzes an ARM instruction to determine the frame size and the offset for the link register (LR).
This function inspects the provided ARM instruction to detect specific types of instructions related to pushing the link register (LR) onto the stack. It calculates the size of the stack frame and determines the offset of the link register, if applicable.
| inst | The ARM instruction to be analyzed (32-bit uint32_teger). |
| offset | Pointer to an integer where the offset of LR will be stored. |
| int backtrace | ( | char * | PC, |
| long * | SP, | ||
| char * | LR | ||
| ) |
Perform a backtrace to find the call stack.
This function attempts to walk the call stack by analyzing the program counter (PC), stack pointer (SP), and link register (LR) to determine the sequence of function calls leading to the current execution point.
The backtrace process works by using the stack and link register to trace the call hierarchy, logging each level of the backtrace, and attempting recovery from any errors. If the backtrace from the stack fails, it will attempt to trace using the link register (LR).
| PC | The current program counter (PC), typically pointing to the instruction where the backtrace starts. |
| SP | The current stack pointer (SP), pointing to the top of the stack. |
| LR | The link register (LR), used to store return addresses for function calls. |
|
inlinestatic |
Checks whether a given program counter (PC) address is within a valid range.
This function checks if the provided PC (program counter) value lies within the memory region between __spl_start and __stack_srv_end. It ensures that the PC value points to a valid memory address in the executable region of the program.
| pc | The program counter value to check. |
|
static |
Perform a backtrace from the Link Register (LR).
This function determines whether the current address is in Thumb mode or ARM mode and calls the appropriate backtrace function based on the result.
| pSP | Pointer to the stack pointer. |
| pPC | Pointer to the program counter. |
| LR | The link register address to backtrace from. |
|
static |
Backtrace from stack based on program counter (PC) state.
This function performs a backtrace by checking if the current code is running in ARM or Thumb state and calls the appropriate backtrace function accordingly. If the program counter (PC) address is invalid, it returns an error.
| pSP | Pointer to the stack pointer. |
| pPC | Pointer to the program counter. |
| pLR | Pointer to the link register. |
| int dump_stack | ( | void | ) |
Dumps the current stack state and performs a backtrace.
This function captures the current program counter (PC), stack pointer (SP), link register (LR), and current processor status register (CPSR). It uses inline assembly to obtain these values, then performs a backtrace to provide insight into the function call stack.
The function also checks if the processor is in THUMB mode based on the CPSR state and adjusts the program counter (PC) accordingly. If the program counter or stack pointer is invalid, the function will return early with a status of 0.
|
static |
Finds the offset for the Link Register (LR) based on the processor state.
This function computes the offset for the Link Register (LR) based on the current processor state (ARM or THUMB) and the instruction sequence at the return address. It checks for specific branch instructions such as bx and blx and adjusts the LR offset accordingly.
The function will also handle both 16-bit and 32-bit instructions based on the processor mode and update the state of the processor.
| LR | A pointer to the Link Register value (the return address). |
| state | A pointer to a boolean representing the processor state. It can be either ARM_STATE or THUMB_STATE. |
|
static |
Perform a backtrace from the Link Register (LR) in Thumb mode.
This function extracts the frame size from the LR and updates the SP and PC based on the Thumb instruction set. It scans the instructions, identifies the backtrace points, and handles stack frame adjustments.
| pSP | Pointer to the stack pointer. |
| pPC | Pointer to the program counter. |
| LR | The link register address to backtrace from. |
|
static |
Perform a backtrace from the stack and retrieve the next return address and program counter (PC).
This function traverses the stack to reconstruct a backtrace by parsing Thumb instructions and calculating the correct stack pointer (SP), program counter (PC), and link register (LR). It uses the Thumb instruction set to decode stack frames and returns the updated SP, PC, and LR values.
| pSP | Pointer to the current stack pointer (SP). |
| pPC | Pointer to the current program counter (PC). |
| pLR | Pointer to the current link register (LR). |
|
static |
Process the return instruction for Thumb mode and determine the frame size.
This function checks if the current instruction is a return instruction, such as "bx lr", which is used for returning from functions in ARM architecture. It specifically handles the case for Thumb mode instructions and sets the frame size appropriately.
| inst | The Thumb instruction to analyze. |
| thumb32bit | Flag indicating if the instruction is Thumb-32 bit (true) or not (false). |
Pop a frame from the stack for Thumb instructions.
This function processes a Thumb instruction to determine the frame size and updates the stack pointer change flag. It distinguishes between normal "pop" and vector "vpop" instructions.
| inst | The Thumb instruction to analyze. |
| sp_change | Pointer to a flag that will be set to 1 if the stack pointer changes. |
| thumb32bit | Flag indicating if the instruction is Thumb-32 bit (true) or not (false). |
|
static |
Calculate the frame size based on the instruction and determine the stack adjustment.
This function analyzes Thumb instructions to determine the frame size of a function prologue, based on push or stack adjustment operations. It handles both 16-bit and 32-bit Thumb instructions.
| inst | The instruction to analyze (32-bit). |
| thumb32bit | Flag indicating whether the instruction is a 32-bit Thumb instruction (1 for Thumb-32, 0 for Thumb-16). |
|
static |
Retrieves the next Thumb instruction from the given addresses.
This function fetches the next instruction in the Thumb instruction set from two 16-bit instruction addresses. It checks whether the instruction is a 32-bit Thumb-2 instruction (Thumb-32), and if so, combines the two 16-bit values to form a 32-bit instruction. It also updates the offset and returns the appropriate instruction.
The function uses the lsb (least significant bit) flag to determine which part of the instruction to select when the instruction is not Thumb-32.
| error | A pointer to an integer that will be set to -1 in case of an error. |
| offset | A pointer to the offset, which will be updated if a Thumb-32 instruction is found. |
| ins16_h_addr | Address of the high part of the instruction (16 bits). |
| ins16_l_addr | Address of the low part of the instruction (16 bits). |
| lsb | Flag indicating whether to fetch the least significant bit of the instruction. |
| thumb32bit | A pointer to an integer that will be set to 1 if a Thumb-32 instruction is detected, otherwise 0. |
Calculate the frame size for a "push" instruction in Thumb mode.
This function checks if the instruction is a "push" instruction or a "sub sp" instruction in Thumb-32 bit mode. It determines the frame size based on the instruction and sets the jump flag if needed.
| inst | The Thumb instruction to analyze. |
| jump | Pointer to a flag that will be set to 1 if the instruction is a "push". |
| thumb32bit | Flag indicating if the instruction is Thumb-32 bit (true) or not (false). |
|
static |
Calculates the frame size for a push or store-multiple instruction that includes the link register (lr).
This function processes a Thumb instruction to determine the frame size (number of registers pushed) based on the presence of the link register (lr). It checks both Thumb-2 (32-bit) and Thumb-1 (16-bit) instructions and computes the frame size accordingly.
| inst | The instruction to analyze (32-bit Thumb instruction). |
| offset | Pointer to an integer that will be set to 1 if a push or store-multiple instruction is found, otherwise 0. |
| thumb32bit | A flag indicating whether the instruction is a 32-bit Thumb instruction (1 if Thumb-32, 0 if Thumb-16). |
-1 if no matching instruction is found.
|
static |
Checks if a given Thumb instruction is a 32-bit Thumb instruction.
This function examines the top 5 bits of the input instruction to determine whether it corresponds to a specific set of Thumb instructions (0x1D, 0x1E, or 0x1F). These values indicate a 32-bit Thumb instruction.
| ic | A 16-bit uint32_teger representing the Thumb instruction to be checked. |
|
extern |
Pointer to the start of the image in memory.
This variable marks the start address of the memory region that contains the program image. It is used to check if a program counter (PC) value falls within the valid range of executable memory.
|
extern |
Pointer to the end of the stack service region.
This variable marks the end address of the memory region used for the stack service. It is used to check if a program counter (PC) value falls within the valid memory region, preventing access to out-of-bounds memory.