CHERIoT RTOS
A compartmentalised RTOS for CHERIoT hardware
Loading...
Searching...
No Matches
assembly-helpers.h
Go to the documentation of this file.
1// Copyright Microsoft and CHERIoT Contributors.
2// SPDX-License-Identifier: MIT
3
4#pragma once
5/**
6 * \file
7 * \brief Helpers for exposing field offsets and structure sizes into
8 * assembly.
9 *
10 * This file provides macros that should be included in both C++ and assembly
11 * files. In C++, they will check (at compile time) that the values are correct
12 * and print a helpful error message if they do not. In assembly, they will
13 * simply expose the values as assembler symbol definitions.
14 */
15
16#ifdef __cplusplus
17/**
18 * Helper class for checking the size of a structure. Used in static
19 * asserts so that the expected size shows up in compiler error messages.
20 */
21template<auto Real, auto Expected>
23{
24 static constexpr bool Value = Real == Expected;
25};
26
27/**
28 * Export a macro into assembly named `name` with value `value`. In C++, this
29 * macro will report an error if the provided value does not equal the constexpr
30 * evaluation of `expression`.
31 */
32# define EXPORT_ASSEMBLY_NAME(name, val) \
33 static_assert(CheckSize<name, val>::Value, \
34 "Value provided for assembly is incorrect");
35
36/**
37 * Export a macro into assembly named `name` with value `value`. In C++, this
38 * macro will report an error if the provided value does not equal the constexpr
39 * evaluation of `expression`.
40 */
41# define EXPORT_ASSEMBLY_EXPRESSION(name, expression, val) \
42 static constexpr size_t name = expression; \
43 static_assert(CheckSize<name, val>::Value, \
44 "Value provided for assembly is incorrect");
45
46/**
47 * Export a macro into assembly of the form `{structure}_offset_{field}`. The
48 * value of this macro will be `value`. In C++, this macro will report an error
49 * if the provided value does not match the compiler's understanding of the
50 * field offset. The error message will contain the correct value.
51 *
52 * This macros also defines a static constexpr value of the same name as the
53 * assembly definition.
54 */
55# define EXPORT_ASSEMBLY_OFFSET(structure, field, val) \
56 static constexpr size_t structure##_offset_##field = val; \
57 static_assert(CheckSize<offsetof(structure, field), val>::Value, \
58 "Offset provided for assembly is incorrect");
59
60/**
61 * Variant of `EXPORT_ASSEMBLY_OFFSET` that can be used to specify the name of
62 * the exported offset. This is useful for providing the offset of fields in
63 * nested structures when assembly code does not need to know the shape of the
64 * overall structure, only the offset of various fields.
65 *
66 * This macros also defines a static constexpr value of the same name as the
67 * assembly definition.
68 */
69# define EXPORT_ASSEMBLY_OFFSET_NAMED(structure, field, value, name) \
70 static constexpr size_t name = value; \
71 EXPORT_ASSEMBLY_OFFSET(structure, field, value)
72/**
73 * Export a macro into assembly of the form `{structure}_size`. The value of
74 * this macro will be `value`. In C++, this macro will report an error if the
75 * provided value does not match the compiler's understanding of the structure
76 * size. The error message will contain the correct value.
77 *
78 * This macros also defines a static constexpr value of the same name as the
79 * assembly definition.
80 */
81# define EXPORT_ASSEMBLY_SIZE(structure, val) \
82 static constexpr size_t structure##_size = val; \
83 static_assert(CheckSize<sizeof(structure), val>::Value, \
84 "Size provided for assembly is incorrect");
85#elif defined(__ASSEMBLER__)
86# define EXPORT_ASSEMBLY_NAME(name, value) .set name, value
87# define EXPORT_ASSEMBLY_EXPRESSION(name, expression, value) .set name, value
88# define EXPORT_ASSEMBLY_OFFSET_NAMED(structure, field, value, name) \
89 .set name, value
90# define EXPORT_ASSEMBLY_OFFSET(structure, field, value) \
91 .set structure##_offset_##field, value
92# define EXPORT_ASSEMBLY_SIZE(structure, value) .set structure##_size, value
93#else
94# define EXPORT_ASSEMBLY_NAME(name, value)
95# define EXPORT_ASSEMBLY_EXPRESSION(name, expression, value)
96# define EXPORT_ASSEMBLY_OFFSET(structure, field, value)
97# define EXPORT_ASSEMBLY_SIZE(structure, name, value)
98# define EXPORT_ASSEMBLY_OFFSET_NAMED(structure, field, value, name)
99#endif
Helper class for checking the size of a structure.