RTEMS
linkersets.h
1 /*
2  * Copyright (c) 2015, 2020 embedded brains GmbH. All rights reserved.
3  *
4  * embedded brains GmbH
5  * Dornierstr. 4
6  * 82178 Puchheim
7  * Germany
8  * <rtems@embedded-brains.de>
9  *
10  * The license and distribution terms for this file may be
11  * found in the file LICENSE in this distribution or at
12  * http://www.rtems.org/license/LICENSE.
13  */
14 
15 #ifndef _RTEMS_LINKERSET_H
16 #define _RTEMS_LINKERSET_H
17 
18 #include <rtems/score/basedefs.h>
19 
20 #ifdef __cplusplus
21 extern "C" {
22 #endif /* __cplusplus */
23 
24 #define RTEMS_LINKER_SET_BEGIN( set ) \
25  _Linker_set_##set##_begin
26 
27 #define RTEMS_LINKER_SET_END( set ) \
28  _Linker_set_##set##_end
29 
30 #define RTEMS_LINKER_ROSET_DECLARE( set, type ) \
31  extern type const RTEMS_LINKER_SET_BEGIN( set )[]; \
32  extern type const RTEMS_LINKER_SET_END( set )[]
33 
34 #define RTEMS_LINKER_ROSET( set, type ) \
35  type const RTEMS_LINKER_SET_BEGIN( set )[ 0 ] \
36  RTEMS_SECTION( ".rtemsroset." #set ".begin" ) RTEMS_USED; \
37  type const RTEMS_LINKER_SET_END( set )[ 0 ] \
38  RTEMS_SECTION( ".rtemsroset." #set ".end" ) RTEMS_USED
39 
40 #define RTEMS_LINKER_ROSET_ITEM_ORDERED_DECLARE( set, type, item, order ) \
41  type const _Linker_set_##set##_##item \
42  RTEMS_SECTION( ".rtemsroset." #set ".content.0." RTEMS_XSTRING( order ) )
43 
44 #define RTEMS_LINKER_ROSET_ITEM_DECLARE( set, type, item ) \
45  extern type const _Linker_set_##set##_##item \
46  RTEMS_SECTION( ".rtemsroset." #set ".content.1" )
47 
48 #define RTEMS_LINKER_ROSET_ITEM_REFERENCE( set, type, item ) \
49  static type const * const _Set_reference_##set##_##item \
50  RTEMS_SECTION( ".rtemsroset.reference" ) RTEMS_USED = \
51  &_Linker_set_##set##_##item
52 
53 #define RTEMS_LINKER_ROSET_ITEM_ORDERED( set, type, item, order ) \
54  type const _Linker_set_##set##_##item \
55  RTEMS_SECTION( ".rtemsroset." #set ".content.0." RTEMS_XSTRING( order ) ) \
56  RTEMS_USED
57 
58 #define RTEMS_LINKER_ROSET_ITEM( set, type, item ) \
59  type const _Linker_set_##set##_##item \
60  RTEMS_SECTION( ".rtemsroset." #set ".content.1" ) RTEMS_USED
61 
62 #define RTEMS_LINKER_ROSET_CONTENT( set, decl ) \
63  decl \
64  RTEMS_SECTION( ".rtemsroset." #set ".content" )
65 
66 #define RTEMS_LINKER_RWSET_DECLARE( set, type ) \
67  extern type RTEMS_LINKER_SET_BEGIN( set )[]; \
68  extern type RTEMS_LINKER_SET_END( set )[]
69 
70 #define RTEMS_LINKER_RWSET( set, type ) \
71  type RTEMS_LINKER_SET_BEGIN( set )[ 0 ] \
72  RTEMS_SECTION( ".rtemsrwset." #set ".begin" ) RTEMS_USED; \
73  type RTEMS_LINKER_SET_END( set )[ 0 ] \
74  RTEMS_SECTION( ".rtemsrwset." #set ".end" ) RTEMS_USED
75 
76 #define RTEMS_LINKER_RWSET_ITEM_ORDERED_DECLARE( set, type, item, order ) \
77  extern type _Linker_set_##set##_##item \
78  RTEMS_SECTION( ".rtemsrwset." #set ".content.0." RTEMS_XSTRING( order ) )
79 
80 #define RTEMS_LINKER_RWSET_ITEM_DECLARE( set, type, item ) \
81  extern type _Linker_set_##set##_##item \
82  RTEMS_SECTION( ".rtemsrwset." #set ".content.1" )
83 
84 /*
85  * The .rtemsroset is here not a typo. We must ensure that the references are
86  * not a victim of the garbage collection of the linker. Thus, we place them
87  * in a dedicated area of the RTEMS read-only linker set section.
88  */
89 #define RTEMS_LINKER_RWSET_ITEM_REFERENCE( set, type, item ) \
90  static type * const _Set_reference_##set##_##item \
91  RTEMS_SECTION( ".rtemsroset.reference" ) RTEMS_USED = \
92  &_Linker_set_##set##_##item
93 
94 #define RTEMS_LINKER_RWSET_ITEM_ORDERED( set, type, item, order ) \
95  type _Linker_set_##set##_##item \
96  RTEMS_SECTION( ".rtemsrwset." #set ".content.0." RTEMS_XSTRING( order ) ) \
97  RTEMS_USED
98 
99 #define RTEMS_LINKER_RWSET_ITEM( set, type, item ) \
100  type _Linker_set_##set##_##item \
101  RTEMS_SECTION( ".rtemsrwset." #set ".content.1" ) RTEMS_USED
102 
103 #define RTEMS_LINKER_RWSET_CONTENT( set, decl ) \
104  decl \
105  RTEMS_SECTION( ".rtemsrwset." #set ".content" )
106 
107 RTEMS_INLINE_ROUTINE uintptr_t _Linker_set_Obfuscate( const void *ptr )
108 {
109  uintptr_t addr;
110 
111  addr = (uintptr_t) ptr;
112  RTEMS_OBFUSCATE_VARIABLE( addr );
113 
114  return addr;
115 }
116 
117 #define RTEMS_LINKER_SET_SIZE( set ) \
118  ( _Linker_set_Obfuscate( RTEMS_LINKER_SET_END( set ) ) \
119  - _Linker_set_Obfuscate( RTEMS_LINKER_SET_BEGIN( set ) ) )
120 
121 #define RTEMS_LINKER_SET_ITEM_COUNT( set ) \
122  ( RTEMS_LINKER_SET_SIZE( set ) \
123  / sizeof( RTEMS_LINKER_SET_BEGIN( set )[ 0 ] ) )
124 
125 #define RTEMS_LINKER_SET_IS_EMPTY( set ) \
126  ( RTEMS_LINKER_SET_SIZE( set ) == 0 )
127 
128 #define RTEMS_LINKER_SET_FOREACH( set, item ) \
129  for ( \
130  item = (void *) _Linker_set_Obfuscate( RTEMS_LINKER_SET_BEGIN( set ) ) ; \
131  item != RTEMS_LINKER_SET_END( set ) ; \
132  ++item \
133  )
134 
135 #ifdef __cplusplus
136 }
137 #endif /* __cplusplus */
138 
139 #endif /* _RTEMS_LINKERSET_H */
#define RTEMS_OBFUSCATE_VARIABLE(_var)
Obfuscates the variable so that the compiler cannot perform optimizations based on the variable value...
Definition: basedefs.h:729
This header file provides basic definitions used by the API and the implementation.
#define RTEMS_INLINE_ROUTINE
Gives a hint to the compiler in a function declaration to inline this function.
Definition: basedefs.h:683