Skip to content

Commit

Permalink
libsel4test: retain _test_type and _test_case
Browse files Browse the repository at this point in the history
unused attribute does not prevent the sections from being
garbage-collected during link-time optimisation. This may trigger
undefined references errors to [__start|__stop]_test_case symbols
that are expected to be emitted by the linker anyway.

Adding "retain" attribute makes sure that the section and its
associated symbols are kept regardless of linker's garbage
collection. Another fix could be adding "nostart-stop-gc" to the
linker flags, but since it is only one section (_test_case)
where its __start/__stop symbols are references, adding retain to
it makes more sense. This additional functionality requires
binutils version 2.36 or later.

Sponsored by: DARPA.

Signed-off-by: Hesham Almatary <hesham.almatary@cl.cam.ac.uk>
  • Loading branch information
heshamelmatary committed Jan 16, 2024
1 parent 3e7b7a8 commit ca8ff11
Showing 1 changed file with 24 additions and 0 deletions.
24 changes: 24 additions & 0 deletions libsel4test/include/sel4test/test.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,18 @@ typedef struct test_type {

/* Declare a test type.
* For now, we put the test types in a separate elf section. */
#if defined(__has_attribute) && __has_attribute(retain)
#define DEFINE_TEST_TYPE(_name, _id, _set_up_test_type, _tear_down_test_type, _set_up, _tear_down, _run_test) \
__attribute__((used,retain)) __attribute__((section("_test_type"))) struct test_type TEST_TYPE_ ##_name = { \
.name = #_name, \
.id = _id, \
.set_up_test_type = _set_up_test_type, \
.tear_down_test_type = _tear_down_test_type, \
.set_up = _set_up, \
.tear_down = _tear_down, \
.run_test = _run_test, \
};
#else
#define DEFINE_TEST_TYPE(_name, _id, _set_up_test_type, _tear_down_test_type, _set_up, _tear_down, _run_test) \
__attribute__((used)) __attribute__((section("_test_type"))) struct test_type TEST_TYPE_ ##_name = { \
.name = #_name, \
Expand All @@ -108,6 +120,7 @@ typedef struct test_type {
.tear_down = _tear_down, \
.run_test = _run_test, \
};
#endif

/* Represents a single testcase.
* Because this struct is used to declare variables that get
Expand All @@ -133,6 +146,16 @@ typedef struct testcase ALIGN(sizeof(struct testcase)) testcase_t;
* C99 style (name = _name, desc = _desc, func = _func...) to make sure
* that it is accepted by C++ compilers.
*/
#if defined(__has_attribute) && __has_attribute(retain)
#define DEFINE_TEST_WITH_TYPE(_name, _description, _function, _test_type, _enabled) \
__attribute__((used,retain)) __attribute__((section("_test_case"))) struct testcase TEST_ ## _name = { \
#_name, \
_description, \
(test_fn)_function, \
_test_type, \
_enabled, \
};
#else
#define DEFINE_TEST_WITH_TYPE(_name, _description, _function, _test_type, _enabled) \
__attribute__((used)) __attribute__((section("_test_case"))) struct testcase TEST_ ## _name = { \
#_name, \
Expand All @@ -141,6 +164,7 @@ typedef struct testcase ALIGN(sizeof(struct testcase)) testcase_t;
_test_type, \
_enabled, \
};
#endif

#define DEFINE_TEST(_name, _description, _function, _enabled) DEFINE_TEST_WITH_TYPE(_name, _description, _function, BASIC, _enabled)

Expand Down

0 comments on commit ca8ff11

Please sign in to comment.