[3/3] doc: sframe: add appendix for generating stack traces

Message ID 20240627183935.921213-4-indu.bhagat@oracle.com
State New
Headers
Series Improvements in SFrame documentation |

Checks

Context Check Description
linaro-tcwg-bot/tcwg_binutils_build--master-arm success Build passed
linaro-tcwg-bot/tcwg_binutils_build--master-aarch64 success Build passed
linaro-tcwg-bot/tcwg_binutils_check--master-aarch64 success Test passed
linaro-tcwg-bot/tcwg_binutils_check--master-arm success Test passed

Commit Message

Indu Bhagat June 27, 2024, 6:39 p.m. UTC
  Add an appendix to provide a rough outline to show how to generate stack
traces using the SFrame format.  Such content should hopefully aid the
reader assimmilate the information in the specification.

libsframe/
	* doc/sframe-spec.texi: Add new appendix.
---
 libsframe/doc/sframe-spec.texi | 54 ++++++++++++++++++++++++++++++++++
 1 file changed, 54 insertions(+)
  

Patch

diff --git a/libsframe/doc/sframe-spec.texi b/libsframe/doc/sframe-spec.texi
index 0cd07843e89..0004d4bd8d3 100644
--- a/libsframe/doc/sframe-spec.texi
+++ b/libsframe/doc/sframe-spec.texi
@@ -823,6 +823,60 @@  Hence, in summary:
 @item 3 @tab FP = CFA + offset3
 @end multitable
 
+@appendix Generating stack traces using SFrame
+
+Following pseudocode highlights how SFrame provides a simple, fast and
+low-overhead mechanism to generate stack traces.
+
+For sake of brevity, only the core algorithm to get the @emph{next frame}
+(given the current frame) is outlined below.  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.  That said, establishing the
+first frame should be trivial:
+
+@noindent
+@code{@ @ @ @ // frame 0} @*
+@code{@ @ @ @ frame->pc = current_IP;} @*
+@code{@ @ @ @ frame->sp = get_reg_value (REG_SP);} @*
+@code{@ @ @ @ frame->fp = get_reg_value (REG_FP);}
+
+Next, given frame N, generating stack trace needs us to get frame N+1.  This
+can be done as follows:
+
+@code {int err = get_next_frame (&frame, pc, sp, fp);}
+
+where @code{get_next_frame} populates the RA, SP, and FP values in the provided
+@code{frame} object and return the error code, if any.  In the following code,
+the @code{sframe_*} functions fetch information from the SFrame section.
+
+@noindent
+@code{@ @ @ @ fre = sframe_find_fre (pc);} @*
+@code{@ @ @ @ if (fre)} @*
+@code{@ @ @ @ @ @ @ @ base_reg = fre->base_fp_p ? REG_FP : REG_SP;} @*
+@code{@ @ @ @ @ @ @ @ cfa_offset = sframe_fre_get_cfa_offset (fre);} @*
+@code{@ @ @ @ @ @ @ @ // Get fixed RA offset or stack offset from FRE as applicable.} @*
+@code{@ @ @ @ @ @ @ @ ra_offset = sframe_fre_get_ra_offset (fre);} @*
+@code{@ @ @ @ @ @ @ @ fp_offset = sframe_fre_get_fp_offset (fre);} @*
+@code{@ @ @ @ @ @ @ @ } @*
+@code{@ @ @ @ @ @ @ @ cfa = base_reg + cfa_offset;} @*
+@code{@ @ @ @ @ @ @ @ frame->sp = cfa;} @*
+@code{@ @ @ @ @ @ @ @ } @*
+@code{@ @ @ @ @ @ @ @ ra_stack_loc = cfa + ra_offset;} @*
+@code{@ @ @ @ @ @ @ @ // Get the address stored in the stack location.} @*
+@code{@ @ @ @ @ @ @ @ frame->pc = read_value (ra_stack_loc);} @*
+@code{@ @ @ @ @ @ @ @ } @*
+@code{@ @ @ @ @ @ @ @ if (fp_offset is VALID)} @*
+@code{@ @ @ @ @ @ @ @ @ @ @ @ fp_stack_loc = cfa + fp_offset;} @*
+@code{@ @ @ @ @ @ @ @ @ @ @ @ // Get the value stored in the stack location.} @*
+@code{@ @ @ @ @ @ @ @ @ @ @ @ frame->fp = read_value (fp_stack_loc);} @*
+@code{@ @ @ @ @ @ @ @ else} @*
+@code{@ @ @ @ @ @ @ @ @ @ @ @ // continue to use the value of fp as it has not} @*
+@code{@ @ @ @ @ @ @ @ @ @ @ @ // been clobbered by the current frame yet.} @*
+@code{@ @ @ @ @ @ @ @ @ @ @ @ frame->fp = fp;} @*
+@code{@ @ @ @ else} @*
+@code{@ @ @ @ @ @ @ @ ret = ERR_NO_SFRAME_FRE}
+
 @node Index
 @unnumbered Index