From 4b579c5f5170e1fb6a0573729444c289643b7d84 Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Tue, 6 Dec 2016 11:35:34 +0100 Subject: score: Simplify linker set API Resurrect RTEMS_LINKER_SET_BEGIN() and RTEMS_LINKER_SET_END(). Add new macros RTEMS_LINKER_SET_ITEM_COUNT(), RTEMS_LINKER_SET_IS_EMPTY(), and RTEMS_LINKER_SET_FOREACH(). Remove confusing RTEMS_LINKER_SET_ASSIGN_BEGIN() and RTEMS_LINKER_SET_ASSIGN_END(). Fix RTEMS_LINKER_SET_SIZE() to return the size in characters as specified by the documentation. Update #2408. Update #2790. --- cpukit/sapi/src/exinit.c | 11 +-- cpukit/score/include/rtems/linkersets.h | 63 +++++++++------- testsuites/sptests/splinkersets01/init.c | 124 ++++++++++++++++++++++++++----- 3 files changed, 145 insertions(+), 53 deletions(-) diff --git a/cpukit/sapi/src/exinit.c b/cpukit/sapi/src/exinit.c index f4bea7c2c3..ed269d5566 100644 --- a/cpukit/sapi/src/exinit.c +++ b/cpukit/sapi/src/exinit.c @@ -131,16 +131,11 @@ RTEMS_SYSINIT_ITEM( void rtems_initialize_executive(void) { - const rtems_sysinit_item *cur; - const rtems_sysinit_item *end; - - RTEMS_LINKER_SET_ASSIGN_BEGIN(_Sysinit, cur ); - RTEMS_LINKER_SET_ASSIGN_END( _Sysinit, end ); + const rtems_sysinit_item *item; /* Invoke the registered system initialization handlers */ - while ( cur != end ) { - ( *cur->handler )(); - ++cur; + RTEMS_LINKER_SET_FOREACH( _Sysinit, item ) { + ( *item->handler )(); } _System_state_Set( SYSTEM_STATE_UP ); diff --git a/cpukit/score/include/rtems/linkersets.h b/cpukit/score/include/rtems/linkersets.h index 390d2cba34..bad046999c 100644 --- a/cpukit/score/include/rtems/linkersets.h +++ b/cpukit/score/include/rtems/linkersets.h @@ -21,35 +21,20 @@ extern "C" { #endif /* __cplusplus */ -#define _LINKER_SET_BEGIN( set ) \ +#define RTEMS_LINKER_SET_BEGIN( set ) \ _Linker_set_##set##_begin -#define _LINKER_SET_END( set ) \ +#define RTEMS_LINKER_SET_END( set ) \ _Linker_set_##set##_end -#define RTEMS_LINKER_SET_ASSIGN_BEGIN( set, item ) \ - do { \ - item = _LINKER_SET_BEGIN( set ); \ - RTEMS_OBFUSCATE_VARIABLE( item ); \ - } while ( 0 ) - -#define RTEMS_LINKER_SET_ASSIGN_END( set, item ) \ - do { \ - item = _LINKER_SET_END( set ); \ - RTEMS_OBFUSCATE_VARIABLE( item ); \ - } while ( 0 ) - -#define RTEMS_LINKER_SET_SIZE( set ) \ - ( (size_t) ( _Linker_set_##set##_end - _Linker_set_##set##_begin ) ) - #define RTEMS_LINKER_ROSET_DECLARE( set, type ) \ - extern type const _LINKER_SET_BEGIN( set )[0]; \ - extern type const _LINKER_SET_END( set )[0] + extern type const RTEMS_LINKER_SET_BEGIN( set )[0]; \ + extern type const RTEMS_LINKER_SET_END( set )[0] #define RTEMS_LINKER_ROSET( set, type ) \ - type const _LINKER_SET_BEGIN( set )[0] \ + type const RTEMS_LINKER_SET_BEGIN( set )[0] \ RTEMS_SECTION( ".rtemsroset." #set ".begin" ) RTEMS_USED; \ - type const _LINKER_SET_END( set )[0] \ + type const RTEMS_LINKER_SET_END( set )[0] \ RTEMS_SECTION( ".rtemsroset." #set ".end" ) RTEMS_USED #define RTEMS_LINKER_ROSET_ITEM_DECLARE( set, type, item ) \ @@ -74,13 +59,13 @@ extern "C" { RTEMS_SECTION( ".rtemsroset." #set ".content" ) #define RTEMS_LINKER_RWSET_DECLARE( set, type ) \ - extern type _LINKER_SET_BEGIN( set )[0]; \ - extern type _LINKER_SET_END( set )[0] + extern type RTEMS_LINKER_SET_BEGIN( set )[0]; \ + extern type RTEMS_LINKER_SET_END( set )[0] #define RTEMS_LINKER_RWSET( set, type ) \ - type _LINKER_SET_BEGIN( set )[0] \ + type RTEMS_LINKER_SET_BEGIN( set )[0] \ RTEMS_SECTION( ".rtemsrwset." #set ".begin" ) RTEMS_USED; \ - type _LINKER_SET_END( set )[0] \ + type RTEMS_LINKER_SET_END( set )[0] \ RTEMS_SECTION( ".rtemsrwset." #set ".end" ) RTEMS_USED #define RTEMS_LINKER_RWSET_ITEM_DECLARE( set, type, item ) \ @@ -109,6 +94,34 @@ extern "C" { decl \ RTEMS_SECTION( ".rtemsrwset." #set ".content" ) +RTEMS_INLINE_ROUTINE uintptr_t _Linker_set_Obfuscate( const void *ptr ) +{ + uintptr_t addr; + + addr = (uintptr_t) ptr; + RTEMS_OBFUSCATE_VARIABLE( addr ); + + return addr; +} + +#define RTEMS_LINKER_SET_SIZE( set ) \ + ( _Linker_set_Obfuscate( RTEMS_LINKER_SET_END( set ) ) \ + - _Linker_set_Obfuscate( RTEMS_LINKER_SET_BEGIN( set ) ) ) + +#define RTEMS_LINKER_SET_ITEM_COUNT( set ) \ + ( RTEMS_LINKER_SET_SIZE( set ) \ + / sizeof( RTEMS_LINKER_SET_BEGIN( set )[ 0 ] ) ) + +#define RTEMS_LINKER_SET_IS_EMPTY( set ) \ + ( RTEMS_LINKER_SET_SIZE( set ) == 0 ) + +#define RTEMS_LINKER_SET_FOREACH( set, item ) \ + for ( \ + item = (void *) _Linker_set_Obfuscate( RTEMS_LINKER_SET_BEGIN( set ) ) ; \ + item != RTEMS_LINKER_SET_END( set ) ; \ + ++item \ + ) + #ifdef __cplusplus } #endif /* __cplusplus */ diff --git a/testsuites/sptests/splinkersets01/init.c b/testsuites/sptests/splinkersets01/init.c index 71f69b79e1..4e19c6e846 100644 --- a/testsuites/sptests/splinkersets01/init.c +++ b/testsuites/sptests/splinkersets01/init.c @@ -83,6 +83,10 @@ ITEM(s2, SAFE_ORDER_C); ITEM(s1, SAFE_ORDER_B); ITEM(s0, SAFE_ORDER_A); +RTEMS_LINKER_RWSET(test_rw_empty, const int *); + +RTEMS_LINKER_ROSET(test_ro_empty, const int *); + static void test(void) { const int **b; @@ -96,29 +100,65 @@ static void test(void) const int * const *sb; const int * const *se; size_t i; - - RTEMS_LINKER_SET_ASSIGN_BEGIN(test_rw, b); - RTEMS_LINKER_SET_ASSIGN_END(test_rw, e); - RTEMS_LINKER_SET_ASSIGN_BEGIN(test_ro, cb); - RTEMS_LINKER_SET_ASSIGN_END(test_ro, ce); - RTEMS_LINKER_SET_ASSIGN_BEGIN(test_rw_i, bi); - RTEMS_LINKER_SET_ASSIGN_END(test_rw_i, ei); - RTEMS_LINKER_SET_ASSIGN_BEGIN(test_ro_i, cbi); - RTEMS_LINKER_SET_ASSIGN_END(test_ro_i, cei); - RTEMS_LINKER_SET_ASSIGN_BEGIN(test_ro_s, sb); - RTEMS_LINKER_SET_ASSIGN_END(test_ro_s, se); + const int **item; + + b = RTEMS_LINKER_SET_BEGIN(test_rw); + e = RTEMS_LINKER_SET_END(test_rw); + cb = RTEMS_LINKER_SET_BEGIN(test_ro); + ce = RTEMS_LINKER_SET_END(test_ro); + bi = RTEMS_LINKER_SET_BEGIN(test_rw_i); + ei = RTEMS_LINKER_SET_END(test_rw_i); + cbi = RTEMS_LINKER_SET_BEGIN(test_ro_i); + cei = RTEMS_LINKER_SET_END(test_ro_i); + sb = RTEMS_LINKER_SET_BEGIN(test_ro_s); + se = RTEMS_LINKER_SET_END(test_ro_s); + RTEMS_OBFUSCATE_VARIABLE(b); + RTEMS_OBFUSCATE_VARIABLE(e); + RTEMS_OBFUSCATE_VARIABLE(cb); + RTEMS_OBFUSCATE_VARIABLE(ce); + RTEMS_OBFUSCATE_VARIABLE(bi); + RTEMS_OBFUSCATE_VARIABLE(ei); + RTEMS_OBFUSCATE_VARIABLE(cbi); + RTEMS_OBFUSCATE_VARIABLE(cei); + RTEMS_OBFUSCATE_VARIABLE(sb); + RTEMS_OBFUSCATE_VARIABLE(se); rtems_test_assert((size_t) (e - b) == RTEMS_ARRAY_SIZE(a)); rtems_test_assert((size_t) (ce - cb) == RTEMS_ARRAY_SIZE(ca)); - rtems_test_assert(RTEMS_LINKER_SET_SIZE(test_rw) == RTEMS_ARRAY_SIZE(a)); - rtems_test_assert(RTEMS_LINKER_SET_SIZE(test_ro) == RTEMS_ARRAY_SIZE(ca)); + rtems_test_assert(RTEMS_LINKER_SET_SIZE(test_rw) == sizeof(a)); + rtems_test_assert(RTEMS_LINKER_SET_SIZE(test_ro) == sizeof(ca)); + rtems_test_assert( + RTEMS_LINKER_SET_ITEM_COUNT(test_rw) == RTEMS_ARRAY_SIZE(a) + ); + rtems_test_assert( + RTEMS_LINKER_SET_ITEM_COUNT(test_ro) == RTEMS_ARRAY_SIZE(ca) + ); + rtems_test_assert(!RTEMS_LINKER_SET_IS_EMPTY(test_rw)); + rtems_test_assert(!RTEMS_LINKER_SET_IS_EMPTY(test_ro)); rtems_test_assert((size_t) (ei - bi) == RTEMS_ARRAY_SIZE(a)); rtems_test_assert((size_t) (cei - cbi) == RTEMS_ARRAY_SIZE(ca)); rtems_test_assert((size_t) (se - sb) == 3); - rtems_test_assert(RTEMS_LINKER_SET_SIZE(test_rw_i) == RTEMS_ARRAY_SIZE(a)); - rtems_test_assert(RTEMS_LINKER_SET_SIZE(test_ro_i) == RTEMS_ARRAY_SIZE(ca)); - rtems_test_assert(RTEMS_LINKER_SET_SIZE(test_ro_s) == 3); + rtems_test_assert(RTEMS_LINKER_SET_SIZE(test_rw_i) == sizeof(a)); + rtems_test_assert(RTEMS_LINKER_SET_SIZE(test_ro_i) == sizeof(ca)); + rtems_test_assert(RTEMS_LINKER_SET_SIZE(test_ro_s) == 3 * sizeof(int *)); + rtems_test_assert( + RTEMS_LINKER_SET_ITEM_COUNT(test_rw_i) == RTEMS_ARRAY_SIZE(a) + ); + rtems_test_assert( + RTEMS_LINKER_SET_ITEM_COUNT(test_ro_i) == RTEMS_ARRAY_SIZE(ca) + ); + rtems_test_assert(RTEMS_LINKER_SET_ITEM_COUNT(test_ro_s) == 3); + rtems_test_assert(!RTEMS_LINKER_SET_IS_EMPTY(test_rw_i)); + rtems_test_assert(!RTEMS_LINKER_SET_IS_EMPTY(test_ro_i)); + rtems_test_assert(!RTEMS_LINKER_SET_IS_EMPTY(test_ro_s)); + + rtems_test_assert(RTEMS_LINKER_SET_SIZE(test_rw_empty) == 0); + rtems_test_assert(RTEMS_LINKER_SET_SIZE(test_ro_empty) == 0); + rtems_test_assert(RTEMS_LINKER_SET_ITEM_COUNT(test_rw_empty) == 0); + rtems_test_assert(RTEMS_LINKER_SET_ITEM_COUNT(test_ro_empty) == 0); + rtems_test_assert(RTEMS_LINKER_SET_IS_EMPTY(test_rw_empty)); + rtems_test_assert(RTEMS_LINKER_SET_IS_EMPTY(test_ro_empty)); for (i = 0; i < RTEMS_ARRAY_SIZE(a); ++i) { rtems_test_assert(&a[i] == b[i]); @@ -136,9 +176,49 @@ static void test(void) rtems_test_assert(&ca[i] == cbi[i]); } + i = 0; + RTEMS_LINKER_SET_FOREACH(test_rw, item) { + rtems_test_assert(&a[i] == *item); + ++i; + } + rtems_test_assert(i == RTEMS_ARRAY_SIZE(a)); + + i = 0; + RTEMS_LINKER_SET_FOREACH(test_ro, item) { + rtems_test_assert(&ca[i] == *item); + ++i; + } + rtems_test_assert(i == RTEMS_ARRAY_SIZE(ca)); + + i = 0; + RTEMS_LINKER_SET_FOREACH(test_rw_i, item) { + rtems_test_assert(&a[i] == *item); + ++i; + } + rtems_test_assert(i == RTEMS_ARRAY_SIZE(a)); + + i = 0; + RTEMS_LINKER_SET_FOREACH(test_ro_i, item) { + rtems_test_assert(&ca[i] == *item); + ++i; + } + rtems_test_assert(i == RTEMS_ARRAY_SIZE(ca)); + rtems_test_assert(&s0 == sb[0]); rtems_test_assert(&s1 == sb[1]); rtems_test_assert(&s2 == sb[2]); + + i = 0; + RTEMS_LINKER_SET_FOREACH(test_rw_empty, item) { + ++i; + } + rtems_test_assert(i == 0); + + i = 0; + RTEMS_LINKER_SET_FOREACH(test_ro_empty, item) { + ++i; + } + rtems_test_assert(i == 0); } static void test_content(void) @@ -148,10 +228,14 @@ static void test_content(void) const char *b_ro; const char *e_ro; - RTEMS_LINKER_SET_ASSIGN_BEGIN(test_content_rw, b_rw); - RTEMS_LINKER_SET_ASSIGN_END(test_content_rw, e_rw); - RTEMS_LINKER_SET_ASSIGN_BEGIN(test_content_ro, b_ro); - RTEMS_LINKER_SET_ASSIGN_END(test_content_ro, e_ro); + b_rw = RTEMS_LINKER_SET_BEGIN(test_content_rw); + e_rw = RTEMS_LINKER_SET_END(test_content_rw); + b_ro = RTEMS_LINKER_SET_BEGIN(test_content_ro); + e_ro = RTEMS_LINKER_SET_END(test_content_ro); + RTEMS_OBFUSCATE_VARIABLE(b_rw); + RTEMS_OBFUSCATE_VARIABLE(e_rw); + RTEMS_OBFUSCATE_VARIABLE(b_ro); + RTEMS_OBFUSCATE_VARIABLE(e_ro); rtems_test_assert((uintptr_t) &content_rw_1 >= (uintptr_t) b_rw); rtems_test_assert((uintptr_t) &content_rw_2 >= (uintptr_t) b_rw); -- cgit v1.2.3