• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1# CFI directives
2
3## Overview
4
5In 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.
6In case of **compiler-generated** code compilers emit special **debug symbols** in resulting binary code and debuggers/profilers use this information.
7`CFI` (**Call Frame Information**) is a subset of these debug symbols which is responsible for correct **stack unwinding**.
8Unfortunately, hand-written assembly lacks of debug symbols and they should be added manually by a programmer.
9
10## Introduction to CFI
11
12In case you need basics please read related wiki article.
13
14## Bridges annotation
15
16Most `asm` bridges have similar layout:
17- Prolog
18- Data preparation for calls
19- Calls
20- Result handling
21- Epilog
22
23From `CFI` perspective, annotation of `prolog` and `epilog` is needed.
24In prolog we save `lr`, `fp` and `callee` regs on stack.
25So we should explicitly mark these stack slots with help of `CFI` directives.
26`Debugger` or `profiler` will use this information in unwinding:
27 - to find the right previous `frame` (with `fp` and `lr` regs)
28 - to restore `callees` in previous frame
29
30In epilog we read saved `callees` from stack and also `fp`/`lr`. Here we annotate that saved registers are restored.
31
32## Non-standard bridges
33
34There are bridges which `hack` stack memory (setting `stack pointer` to other stack frame), i.e.:
35- Deoptimization, all bridges
36- OsrEntryAfterCFrame
37
38These bridges return control flow to code which has not called them.
39![cfi_hack_bridges](images/cfi_hack_bridges.png)
40
41In 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