1b1994897Sopenharmony_ci# CFI directives
2b1994897Sopenharmony_ci
3b1994897Sopenharmony_ci## Overview
4b1994897Sopenharmony_ci
5b1994897Sopenharmony_ciIn some situations **hand-written** assembly code is preferred to compiler-generated, i.e. for performance reasons (usage of special cryptographic/vector instructions) or if there is a need for manual stack/registers manipulation.
6b1994897Sopenharmony_ciIn case of **compiler-generated** code compilers emit special **debug symbols** in resulting binary code and debuggers/profilers use this information.  
7b1994897Sopenharmony_ci`CFI` (**Call Frame Information**) is a subset of these debug symbols which is responsible for correct **stack unwinding**.
8b1994897Sopenharmony_ciUnfortunately, hand-written assembly lacks of debug symbols and they should be added manually by a programmer.
9b1994897Sopenharmony_ci
10b1994897Sopenharmony_ci## Introduction to CFI
11b1994897Sopenharmony_ci
12b1994897Sopenharmony_ciIn case you need basics please read related wiki article.
13b1994897Sopenharmony_ci
14b1994897Sopenharmony_ci## Bridges annotation
15b1994897Sopenharmony_ci
16b1994897Sopenharmony_ciMost `asm` bridges have similar layout:
17b1994897Sopenharmony_ci- Prolog
18b1994897Sopenharmony_ci- Data preparation for calls
19b1994897Sopenharmony_ci- Calls
20b1994897Sopenharmony_ci- Result handling
21b1994897Sopenharmony_ci- Epilog
22b1994897Sopenharmony_ci
23b1994897Sopenharmony_ciFrom `CFI` perspective, annotation of `prolog` and `epilog` is needed.
24b1994897Sopenharmony_ciIn prolog we save `lr`, `fp` and `callee` regs on stack.
25b1994897Sopenharmony_ciSo we should explicitly mark these stack slots with help of `CFI` directives.
26b1994897Sopenharmony_ci`Debugger` or `profiler` will use this information in unwinding:
27b1994897Sopenharmony_ci - to find the right previous `frame` (with `fp` and `lr` regs)
28b1994897Sopenharmony_ci - to restore `callees` in previous frame
29b1994897Sopenharmony_ci
30b1994897Sopenharmony_ciIn epilog we read saved `callees` from stack and also `fp`/`lr`. Here we annotate that saved registers are restored.
31b1994897Sopenharmony_ci
32b1994897Sopenharmony_ci## Non-standard bridges
33b1994897Sopenharmony_ci
34b1994897Sopenharmony_ciThere are bridges which `hack` stack memory (setting `stack pointer` to other stack frame), i.e.:
35b1994897Sopenharmony_ci- Deoptimization, all bridges
36b1994897Sopenharmony_ci- OsrEntryAfterCFrame
37b1994897Sopenharmony_ci
38b1994897Sopenharmony_ciThese bridges return control flow to code which has not called them.  
39b1994897Sopenharmony_ci![cfi_hack_bridges](images/cfi_hack_bridges.png)
40b1994897Sopenharmony_ci
41b1994897Sopenharmony_ciIn that case we "say" to `debugger` that we are not going to return to previous frame. So we directly specify other frame in which we will return + spot slots for `callees` (it can be `callee` slots in `cframe` or `boundary frame`).
42