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 27, 2024
1 parent 273deba commit 05fc543
Showing 1 changed file with 10 additions and 2 deletions.
12 changes: 10 additions & 2 deletions libsel4test/include/sel4test/test.h
Original file line number Diff line number Diff line change
Expand Up @@ -96,10 +96,17 @@ typedef struct test_type {
test_result_t (*run_test)(struct testcase *test, uintptr_t e);
} ALIGN(32) test_type_t;

#if defined(__has_attribute) && __has_attribute(retain)
#define ATTR_USED_RETAIN __attribute__((used,retain))
#else
#define ATTR_USED_RETAIN __attribute__((used))
#endif

/* Declare a test type.
* For now, we put the test types in a separate elf section. */
#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 = { \
ATTR_USED_RETAIN __attribute__((section("_test_type"))) \
struct test_type TEST_TYPE_ ##_name = { \
.name = #_name, \
.id = _id, \
.set_up_test_type = _set_up_test_type, \
Expand Down Expand Up @@ -134,7 +141,8 @@ typedef struct testcase ALIGN(sizeof(struct testcase)) testcase_t;
* that it is accepted by C++ compilers.
*/
#define DEFINE_TEST_WITH_TYPE(_name, _description, _function, _test_type, _enabled) \
__attribute__((used)) __attribute__((section("_test_case"))) struct testcase TEST_ ## _name = { \
ATTR_USED_RETAIN __attribute__((section("_test_case"))) \
struct testcase TEST_ ## _name = { \
#_name, \
_description, \
(test_fn)_function, \
Expand Down

0 comments on commit 05fc543

Please sign in to comment.