![]() |
libdragon
|
Go to the source code of this file.
Data Structures | |
struct | bt_func_t |
Description of a function for the purpose of backtracing (filled by __bt_analyze_func) More... | |
Enumerations | |
enum | bt_func_type { BT_FUNCTION , BT_FUNCTION_FRAMEPOINTER , BT_EXCEPTION , BT_LEAF } |
The "type" of funciton as categorized by the backtrace heuristic (__bt_analyze_func) More... | |
Functions | |
bool | __bt_analyze_func (bt_func_t *func, uint32_t *ptr, uint32_t func_start, bool from_exception) |
Analyze a function to find out its stack frame layout and properties (useful for backtracing). | |
int | __backtrace_from (void **buffer, int size, uint32_t *pc, uint32_t *sp, uint32_t *fp, uint32_t *exception_ra) |
Like backtrace, but start from an arbitrary context. Useful for backtracing a thread. | |
char * | __symbolize (void *vaddr, char *buf, int size) |
Return the symbol associated to a given address. | |
struct bt_func_t |
Description of a function for the purpose of backtracing (filled by __bt_analyze_func)
Data Fields | ||
---|---|---|
bt_func_type | type | Type of the function. |
int | stack_size | Size of the stack frame. |
int | ra_offset | Offset of the return address from the top of the stack frame. |
int | fp_offset | Offset of the saved fp from the top of the stack frame; this is != 0 only if the function modifies fp (maybe as a frame pointer, but not necessarily) |
enum bt_func_type |
The "type" of funciton as categorized by the backtrace heuristic (__bt_analyze_func)
bool __bt_analyze_func | ( | bt_func_t * | func, |
uint32_t * | ptr, | ||
uint32_t | func_start, | ||
bool | from_exception | ||
) |
Analyze a function to find out its stack frame layout and properties (useful for backtracing).
This function implements the core heuristic used by the backtrace engine. It analyzes the actual code of a function in memory instruction by instruction, trying to find out whether the function uses a stack frame or not, whether it uses a frame pointer, and where the return address is stored.
Since we do not have DWARF informations or similar metadata, we can just do educated guesses. A mistake in the heuristic will result probably in a wrong backtrace from this point on.
The heuristic works as follows:
sd $ra, nn($sp)
), and an instruction creating the stack frame (eg: addiu $sp, $sp, -nn
). Once both are found, the heuristic knows how to fill in .stack_size
and .ra_offset
fields of the function description structure, and it can stop.move $fp, $sp
, it knows that the function uses $fp as frame pointer, and will mark the function as BT_FUNCTION_FRAMEPOINTER. In any case, the field .fp_offset
will be filled in with the offset in the stack where $fp is stored, so that the backtrace engine can track the current value of the register in any case.func | Output function description structure |
ptr | Pointer to the function code at the point where the backtrace starts. This is normally the point where a JAL opcode is found, as we are walking up the call stack. |
func_start | Start of the function being analyzed. This is optional: the heuristic can work without this hint, but it is useful in certain situations (eg: to better walk up after an exception). |
from_exception | If true, this function was interrupted by an exception. This is a hint that the function might even be a leaf function without a stack frame, and that we must use special heuristics for it. |
char * __symbolize | ( | void * | vaddr, |
char * | buf, | ||
int | size | ||
) |
Return the symbol associated to a given address.
This function inspect the symbol table (if any) to search for the specified address. It returns the function name the address belongs to, and the offset within the function as a string in the format "function_name+0x1234".
If the symbol table is not found in the rompack or the address is not found, the return string is "???".
vaddr | Address to symbolize |
buf | Buffer where to store the result |
size | Size of the buffer |