1# Style guide 2 3Hafnium's coding style has been based on the 4[Linux style](https://www.kernel.org/doc/html/v4.17/process/coding-style.html) 5with explicit modifications: 6 7* Always use braces for conditionals and loops. (No SSL `goto fail;`, thanks.) 8 9Following this, we generally fall back to the subset of the 10[Google C++ style guide](https://google.github.io/styleguide/cppguide.html) that 11is applicable to C. 12 13We try to automate this where possible with clang-format and clang-tidy but that 14doesn't capture everything we'd like today. Where the style enforced by this 15tooling conflicts with what is in this document we accept what the tooling 16requires, and try to improve it if possible. 17 18## Clarifications 19 20* Yes, it does mean all variables are declared, C90-style, at the top of 21 scope, even those loop induction variables. 22* Linux encourages no braces around single-statement branches. We follow 23 Google and require braces around all scope blocks. 24 25## Naming symbols 26 27* Arch-specific functions should start with `arch_`. 28* Platform-specific functions should start with `plat_`. 29* Non-static functions should generally start with the name of the file they 30 are declared in (after the `arch_` or `plat_` prefix if appropriate), though 31 there are quite a few exceptions to this rule. 32* Prefer `x_count` over `num_x`. 33 34## Prose 35 36These rules apply to comments and other natural language text. 37 38* Capitalize acronyms. 39 * CPU, vCPU, VM, EL2, FF-A, QEMU 40* Spell out Hafnium in full, not Hf. 41* Use single spaces. 42* Sentences end with full stops. 43* If the comment fits on one line use `/* */`, otherwise space it out: 44 45 ``` 46 /* 47 * Informative long comment 48 * with extra information. 49 */ 50 ``` 51 52* Doc-ish comments start with `/**`. 53 54 * Use for: 55 * Function definitions (not declarations) 56 * Struct declarations 57 * Enum values 58 * Do not use for: 59 * Macros 60 * Definitions of globals 61 62* References to code symbols use backticks, e.g. `` `my_symbol` ``. 63 64## Coding practices 65 66* Function macros should be functions instead, that way you get types. 67* Lock ordering is described at the top of [`api.c`](../../src/api.c). 68* Use opaque types to avoid implicit casts when it will help avoid mistakes. 69 e.g. [`addr.h`](../../inc/hf/addr.h) 70* Avoid inline casting. C doesn't give much protection so be formal about the 71 transformations. e.g. [`addr.h`](../../inc/hf/addr.h) 72* If a function acquires a resource, there must be a single exit path to free 73 the resource. Tracking down multiple exit points is hard and requires 74 duplicated code which is harder. This may require splitting functions into 75 subfunctions. Early exit is okay if there aren't any clean up tasks. 76* Don't use function pointers. It makes analysis hard and is often a target of 77 attacks. 78* Be liberal with `CHECK`. Use it to assert pre-/post- conditions. 79* No self-modifying code. 80* Build targets should include all the direct dependencies for their sources, 81 where possible, rather than relying on transitive dependencies. 82 83## Logging 84 85Hafnium uses the same log levels as Arm Trusted Firmware. There are 5 log 86levels, in order of severity: 87 881. `ERROR` 89 90 Use this only for cases that there is an error in the hypervisor itself, 91 perhaps caused by a coding error, bad configuration, unexpected hardware 92 behaviour or a malformed manifest. Errors should not be logged during normal 93 operation, even in case of a buggy or malicious VM. 94 952. `NOTICE` 96 97 Use this sparingly for important messages which should be logged even in 98 production builds because they will be useful for debugging. This is a 99 suitable level to use for events which may indicate a bug in a VM. 100 1013. `WARNING` 102 103 Use this for warnings which are important to developers but can generally be 104 ignored in production. 105 1064. `INFO` 107 108 Use this to provide extra information that is helpful for developers. 109 1105. `VERBOSE` 111 112 Use this to provide even more information which may be helpful when tracing 113 through execution in detail, such as when debugging test failures. This is 114 the only level which should include any sensitive data. 115 116Logging is done with the `dlog_*` macros, e.g. `dlog_info`. These accept 117printf-style format strings and arguments. 118 119The log level of a build is controlled by the `log_level` argument defined in 120[`BUILDCONFIG.gn`](../../build/BUILDCONFIG.gn). This defaults to `INFO` for debug 121builds and tests, meaning that all levels except `VERBOSE` will be logged. It is 122recommended to set the log level to `NOTICE` for production builds, to reduce 123binary size and log spam. 124