diff options
-rw-r--r-- | libsframe/doc/sframe-spec.texi | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/libsframe/doc/sframe-spec.texi b/libsframe/doc/sframe-spec.texi index be5a588..c1730ad 100644 --- a/libsframe/doc/sframe-spec.texi +++ b/libsframe/doc/sframe-spec.texi @@ -54,6 +54,9 @@ low-overhead mechanism to generate stack traces. * SFrame Section:: * ABI/arch-specific Definition:: +Appendices +* Generating Stack Traces using SFrame:: + * Index:: @end menu @@ -823,6 +826,87 @@ Hence, in summary: @item 3 @tab FP = CFA + offset3 @end multitable +@node Generating Stack Traces using SFrame +@appendix Generating Stack Traces using SFrame + +Using some C-like pseudocode, this section highlights how SFrame provides a +simple, fast and low-overhead mechanism to generate stack traces. Needless to +say that for generating accurate and useful stack traces, several other aspects +will need attention: finding and decoding bits of SFrame section(s) in the +program binary, symbolization of addresses, to name a few. + +In the current context, a @code{frame} is the abstract construct that +encapsulates the following information: +@itemize @minus +@item +program counter (PC), +@item +stack pointer (SP), and +@item +frame pointer (FP) +@end itemize + +With that said, establishing the first @code{frame} should be trivial: + +@example + // frame 0 + frame->pc = current_IP; + frame->sp = get_reg_value (REG_SP); + frame->fp = get_reg_value (REG_FP); +@end example + +where @code{REG_SP} and @code{REG_FP} are are ABI-designated stack pointer and +frame pointer registers respectively. + +Next, given frame N, generating stack trace needs us to get frame N+1. This +can be done as follows: + +@example + // Get the PC, SP, and FP for frame N. + pc = frame->pc; + sp = frame->sp; + fp = frame->fp; + // Populate frame N+1. + int err = get_next_frame (&next_frame, pc, sp, fp); +@end example + +where given the values of the program counter, stack pointer and frame pointer +from frame N, @code{get_next_frame} populates the provided @code{next_frame} +object and returns the error code, if any. In the following pseudocode for +@code{get_next_frame}, the @code{sframe_*} functions fetch information from the +SFrame section. + +@example + fre = sframe_find_fre (pc); + if (fre) + // Whether the base register for CFA tracking is REG_FP. + base_reg_val = sframe_fre_base_reg_fp_p (fre) ? fp : sp; + // Get the CFA stack offset from the FRE. + cfa_offset = sframe_fre_get_cfa_offset (fre); + // Get the fixed RA offset or FRE stack offset as applicable. + ra_offset = sframe_fre_get_ra_offset (fre); + // Get the fixed FP offset or FRE stack offset as applicable. + fp_offset = sframe_fre_get_fp_offset (fre); + + cfa = base_reg_val + cfa_offset; + next_frame->sp = cfa; + + ra_stack_loc = cfa + ra_offset; + // Get the address stored in the stack location. + next_frame->pc = read_value (ra_stack_loc); + + if (fp_offset is VALID) + fp_stack_loc = cfa + fp_offset; + // Get the value stored in the stack location. + next_frame->fp = read_value (fp_stack_loc); + else + // Continue to use the value of fp as it has not + // been clobbered by the current frame yet. + next_frame->fp = fp; + else + ret = ERR_NO_SFRAME_FRE; +@end example + @node Index @unnumbered Index |