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.
This commit is contained in:
Sebastian Huber
2016-12-06 11:35:34 +01:00
parent 38bc13f809
commit 4b579c5f51
3 changed files with 144 additions and 52 deletions

View File

@@ -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 );

View File

@@ -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 */

View File

@@ -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;
const int **item;
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);
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);