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 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