/* $Id: VBox-CodingGuidelines.cpp $ */ /** @file * VBox - Coding Guidelines. */ /* * Copyright (C) 2006-2022 Oracle and/or its affiliates. * * This file is part of VirtualBox base platform packages, as * available from https://www.virtualbox.org. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation, in version 3 of the * License. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, see . * * SPDX-License-Identifier: GPL-3.0-only */ /** @page pg_vbox_guideline VBox Coding Guidelines * * The compulsory sections of these guidelines are to be followed in all of the * VBox sources. Please note that local guidelines in parts of the VBox source * tree may promote the optional ones to compulsory status. The VBox tree also * contains some 3rd party sources where it is good to follow the local coding * style while keeping these guidelines in mind. * * Contents: * - @ref sec_vbox_guideline_compulsory * - @ref sec_vbox_guideline_compulsory_sub64 * - @ref sec_vbox_guideline_compulsory_cppmain * - @ref sec_vbox_guideline_compulsory_cppqtgui * - @ref sec_vbox_guideline_compulsory_xslt * - @ref sec_vbox_guideline_compulsory_doxygen * - @ref sec_vbox_guideline_compulsory_guest * - @ref sec_vbox_guideline_optional * - @ref sec_vbox_guideline_optional_layout * - @ref sec_vbox_guideline_optional_prefix * - @ref sec_vbox_guideline_optional_misc * - @ref sec_vbox_guideline_warnings * - @ref sec_vbox_guideline_warnings_signed_unsigned_compare * - @ref sec_vbox_guideline_svn * * Local guidelines overrides: * - src/VBox/VMM/: @ref pg_vmm_guideline (src/VBox/VMM/Docs-CodingGuidelines.cpp) * - src/VBox/ValidationKit/: @ref pg_validationkit_guideline (src/VBox/ValidationKit/ValidationKitCodingGuidelines.cpp) * - src/VBox/Runtime/: All of @ref sec_vbox_guideline_optional is mandatory. * - src/VBox/Main/: @ref sec_vbox_guideline_compulsory_cppmain * - src/VBox/Frontends/VirtualBox/: @ref sec_vbox_guideline_compulsory_cppqtgui * * * @section sec_vbox_guideline_compulsory Compulsory * * * * (1) It is common practice on Unix to have a single symbol namespace for an * entire process. If one is careless symbols might be resolved in a * different way that one expects, leading to weird problems. * * (2) This is common practice among most projects dealing with modules in * shared libraries. The Windows / PE __declspect(import) and * __declspect(export) constructs are the main reason for this. * OTOH, we do perhaps have a bit too detailed graining of this in VMM... * * (3) There are guys out there grepping public sources for symbols leading with * single and double underscores as well as gotos and other things * considered bad practice. They'll post statistics on how bad our sources * are on some mailing list, forum or similar. * * * @subsection sec_vbox_guideline_compulsory_sub64 64-bit and 32-bit * * Here are some amendments which address 64-bit vs. 32-bit portability issues. * * Some facts first: * * * * Now for the guidelines: * * * * @subsubsection sec_vbox_guideline_compulsory_sub64_comp Comparing the GCC and MSC calling conventions * * GCC expects the following (cut & past from page 20 in the ABI draft 0.96): * * @verbatim %rax temporary register; with variable arguments passes information about the number of SSE registers used; 1st return register. [Not preserved] %rbx callee-saved register; optionally used as base pointer. [Preserved] %rcx used to pass 4th integer argument to functions. [Not preserved] %rdx used to pass 3rd argument to functions; 2nd return register [Not preserved] %rsp stack pointer [Preserved] %rbp callee-saved register; optionally used as frame pointer [Preserved] %rsi used to pass 2nd argument to functions [Not preserved] %rdi used to pass 1st argument to functions [Not preserved] %r8 used to pass 5th argument to functions [Not preserved] %r9 used to pass 6th argument to functions [Not preserved] %r10 temporary register, used for passing a function's static chain pointer [Not preserved] %r11 temporary register [Not preserved] %r12-r15 callee-saved registers [Preserved] %xmm0-%xmm1 used to pass and return floating point arguments [Not preserved] %xmm2-%xmm7 used to pass floating point arguments [Not preserved] %xmm8-%xmm15 temporary registers [Not preserved] %mmx0-%mmx7 temporary registers [Not preserved] %st0 temporary register; used to return long double arguments [Not preserved] %st1 temporary registers; used to return long double arguments [Not preserved] %st2-%st7 temporary registers [Not preserved] %fs Reserved for system use (as thread specific data register) [Not preserved] @endverbatim * * Direction flag is preserved as cleared. * The stack must be aligned on a 16-byte boundary before the 'call/jmp' instruction. * * MSC expects the following: * @verbatim rax return value, not preserved. rbx preserved. rcx 1st argument, integer, not preserved. rdx 2nd argument, integer, not preserved. rbp preserved. rsp preserved. rsi preserved. rdi preserved. r8 3rd argument, integer, not preserved. r9 4th argument, integer, not preserved. r10 scratch register, not preserved. r11 scratch register, not preserved. r12-r15 preserved. xmm0 1st argument, fp, return value, not preserved. xmm1 2st argument, fp, not preserved. xmm2 3st argument, fp, not preserved. xmm3 4st argument, fp, not preserved. xmm4-xmm5 scratch, not preserved. xmm6-xmm15 preserved. @endverbatim * * Dunno what the direction flag is... * The stack must be aligned on a 16-byte boundary before the 'call/jmp' instruction. * * * @subsection sec_vbox_guideline_compulsory_cppmain C++ guidelines for Main * * Since the Main API code is a large amount of C++ code, it is allowed but * not required to use C++ style comments (as permanent comments, beyond the * temporary use allowed by the general coding guideline). This is a weak * preference, i.e. large scale comment style changes are not encouraged. * * Main is currently (2009) full of hard-to-maintain code that uses complicated * templates. The new mid-term goal for Main is to have less custom templates * instead of more for the following reasons: * * * * In particular, the following bits should be considered deprecated and should * NOT be used in new code: * * * * Generally, in many cases, a simple class with a proper destructor can achieve * the same effect as a 1,000-line template include file, and the code is * much more accessible that way. * * Using standard STL templates like std::list, std::vector and std::map is OK. * Exceptions are: * * * * @subsection sec_vbox_guideline_compulsory_cppqtgui C++ guidelines for the Qt GUI * * The Qt GUI is currently (2010) on its way to become more compatible to the * rest of VirtualBox coding style wise. From now on, all the coding style * rules described in this file are also mandatory for the Qt GUI. Additionally * the following rules should be respected: * * * * * @subsection sec_vbox_guideline_compulsory_xslt XSLT * * XSLT (eXtensible Stylesheet Language Transformations) is used quite a bit in * the Main API area of VirtualBox to generate sources and bindings to that API. * There are a couple of common pitfalls worth mentioning: * * * * * @subsection sec_vbox_guideline_compulsory_doxygen Doxygen Comments * * As mentioned above, we shall use doxygen/javadoc style commenting of public * functions, typedefs, classes and such. It is mandatory to use this style * everywhere! * * A couple of hints on how to best write doxygen comments: * * * * See https://www.stack.nl/~dimitri/doxygen/manual/index.html for the official * doxygen documention. * * * * @subsection sec_vbox_guideline_compulsory_guest Handling of guest input * * First, guest input should ALWAYS be consider to be TOXIC and constructed with * MALICIOUS intent! Max paranoia level! * * Second, when getting inputs from memory shared with the guest, be EXTREMELY * careful to not re-read input from shared memory after validating it, because * that will create TOCTOU problems. So, after reading input from shared memory * always use the RT_UNTRUSTED_NONVOLATILE_COPY_FENCE() macro. For more details * on TOCTOU: https://en.wikipedia.org/wiki/Time_of_check_to_time_of_use * * Thirdly, considering the recent speculation side channel issues, spectre v1 * in particular, we would like to be ready for future screwups. This means * having input validation in a separate block of code that ends with one (or * more) RT_UNTRUSTED_VALIDATED_FENCE(). * * So the rules: * * * * * Problem patterns: * - https://en.wikipedia.org/wiki/Time_of_check_to_time_of_use * - https://googleprojectzero.blogspot.de/2018/01/reading-privileged-memory-with-side.html * (Variant 1 only). * - https://en.wikipedia.org/wiki/Integer_overflow * * * * @section sec_vbox_guideline_optional Optional * * First part is the actual coding style and all the prefixes. The second part * is a bunch of good advice. * * * @subsection sec_vbox_guideline_optional_layout The code layout * * * * @subsection sec_vbox_guideline_optional_prefix Variable / Member Prefixes * * Prefixes are meant to provide extra context clues to a variable/member, we * therefore avoid using prefixes that just indicating the type if a better * choice is available. * * * The prefixes: * * * * (1) Except in the occasional 'pcsz' prefix, the 'c' prefix is never ever * used in the meaning 'const'. * * * @subsection sec_vbox_guideline_optional_misc Misc / Advice / Stuff * * * * (1) Important, be very careful with the casting. In particular, note that * a compiler might treat pointers as signed (IIRC). * * (2) "A really advanced hacker comes to understand the true inner workings of * the machine - he sees through the language he's working in and glimpses * the secret functioning of the binary code - becomes a Ba'al Shem of * sorts." (Neal Stephenson "Snow Crash") * * * * @section sec_vbox_guideline_warnings Compiler Warnings * * The code should when possible compile on all platforms and compilers without any * warnings. That's a nice idea, however, if it means making the code harder to read, * less portable, unreliable or similar, the warning should not be fixed. * * Some of the warnings can seem kind of innocent at first glance. So, let's take the * most common ones and explain them. * * * @subsection sec_vbox_guideline_warnings_signed_unsigned_compare Signed / Unsigned Compare * * GCC says: "warning: comparison between signed and unsigned integer expressions" * MSC says: "warning C4018: '<|<=|==|>=|>' : signed/unsigned mismatch" * * The following example will not output what you expect: @code #include int main() { signed long a = -1; unsigned long b = 2294967295; if (a < b) printf("%ld < %lu: true\n", a, b); else printf("%ld < %lu: false\n", a, b); return 0; } @endcode * If I understood it correctly, the compiler will convert a to an * unsigned long before doing the compare. * * * * @section sec_vbox_guideline_svn Subversion Commit Rules * * * Before checking in: * * * * After checking in: * * * * (Inspired by mozilla tree rules.) * * */