Back to home page

LXR

 
 

    


File indexing completed on 2025-05-11 08:24:13

0001 /* SPDX-License-Identifier: BSD-2-Clause */
0002 
0003 /**
0004  * @file
0005  *
0006  * @ingroup RTEMSAPILinkerSets
0007  *
0008  * @brief This header file provides the linker sets API.
0009  */
0010 
0011 /*
0012  * Copyright (C) 2015, 2020 embedded brains GmbH & Co. KG
0013  *
0014  * Redistribution and use in source and binary forms, with or without
0015  * modification, are permitted provided that the following conditions
0016  * are met:
0017  * 1. Redistributions of source code must retain the above copyright
0018  *    notice, this list of conditions and the following disclaimer.
0019  * 2. Redistributions in binary form must reproduce the above copyright
0020  *    notice, this list of conditions and the following disclaimer in the
0021  *    documentation and/or other materials provided with the distribution.
0022  *
0023  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0024  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0025  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0026  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0027  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0028  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0029  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0030  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0031  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0032  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0033  * POSSIBILITY OF SUCH DAMAGE.
0034  */
0035 
0036 #ifndef _RTEMS_LINKERSET_H
0037 #define _RTEMS_LINKERSET_H
0038 
0039 #include <rtems/score/basedefs.h>
0040 
0041 #ifdef __cplusplus
0042 extern "C" {
0043 #endif /* __cplusplus */
0044 
0045 /**
0046  * @ingroup RTEMSImpl
0047  *
0048  * @brief Obfuscates a pointer to prevent compiler optimizations.
0049  *
0050  * @param ptr is the pointer to obfuscate.
0051  *
0052  * @return Returns the unsigned integer representation of the obfuscated
0053  *   pointer.
0054  */
0055 static inline uintptr_t _Linker_set_Obfuscate( const void *ptr )
0056 {
0057   uintptr_t addr;
0058 
0059   addr = (uintptr_t) ptr;
0060   RTEMS_OBFUSCATE_VARIABLE( addr );
0061 
0062   return addr;
0063 }
0064 
0065 /**
0066  * @defgroup RTEMSAPILinkerSets Linker Sets
0067  *
0068  * @ingroup RTEMSAPI
0069  *
0070  * @brief This group contains the linker sets API.
0071  *
0072  * @{
0073  */
0074 
0075 #define RTEMS_LINKER_SET_BEGIN( set ) \
0076   _Linker_set_##set##_begin
0077 
0078 #define RTEMS_LINKER_SET_END( set ) \
0079   _Linker_set_##set##_end
0080 
0081 /*
0082  * Modern GCC optimizes for speed which may insert padding between linker
0083  * sections that previous versions avoided. Alignment must now be explicit to
0084  * maintain the behavior of previous versions.
0085  */
0086 #define RTEMS_LINKER_SET_ALIGN( type ) \
0087   RTEMS_ALIGNED( RTEMS_ALIGNOF( type ) )
0088 
0089 #define RTEMS_LINKER_ROSET_DECLARE( set, type ) \
0090   extern RTEMS_LINKER_SET_ALIGN( type ) type    \
0091   const RTEMS_LINKER_SET_BEGIN( set )[];    \
0092   extern RTEMS_LINKER_SET_ALIGN( type ) type    \
0093   const RTEMS_LINKER_SET_END( set )[]
0094 
0095 #define RTEMS_LINKER_ROSET( set, type ) \
0096   RTEMS_LINKER_SET_ALIGN( type ) type const RTEMS_LINKER_SET_BEGIN( set )[ 0 ] \
0097   RTEMS_SECTION( ".rtemsroset." #set ".begin" ) RTEMS_USED; \
0098   RTEMS_LINKER_SET_ALIGN( type ) type const RTEMS_LINKER_SET_END( set )[ 0 ] \
0099   RTEMS_SECTION( ".rtemsroset." #set ".end" ) RTEMS_USED
0100 
0101 #define RTEMS_LINKER_ROSET_ITEM_ORDERED_DECLARE( set, type, item, order ) \
0102   extern RTEMS_LINKER_SET_ALIGN( type ) type const _Linker_set_##set##_##item \
0103   RTEMS_SECTION( ".rtemsroset." #set ".content.0." RTEMS_XSTRING( order ) )
0104 
0105 #define RTEMS_LINKER_ROSET_ITEM_DECLARE( set, type, item ) \
0106   extern RTEMS_LINKER_SET_ALIGN( type ) type const _Linker_set_##set##_##item \
0107   RTEMS_SECTION( ".rtemsroset." #set ".content.1" )
0108 
0109 #define RTEMS_LINKER_ROSET_ITEM_REFERENCE( set, type, item )    \
0110   static RTEMS_LINKER_SET_ALIGN( type ) type            \
0111   const * const _Set_reference_##set##_##item           \
0112   RTEMS_SECTION( ".rtemsroset.reference" ) RTEMS_USED =     \
0113   &_Linker_set_##set##_##item
0114 
0115 #define RTEMS_LINKER_ROSET_ITEM_ORDERED( set, type, item, order ) \
0116   RTEMS_LINKER_SET_ALIGN( type ) type const _Linker_set_##set##_##item \
0117   RTEMS_SECTION( ".rtemsroset." #set ".content.0." RTEMS_XSTRING( order ) ) \
0118   RTEMS_USED
0119 
0120 #define RTEMS_LINKER_ROSET_ITEM( set, type, item ) \
0121   RTEMS_LINKER_SET_ALIGN( type ) type const _Linker_set_##set##_##item \
0122   RTEMS_SECTION( ".rtemsroset." #set ".content.1" ) RTEMS_USED
0123 
0124 #define RTEMS_LINKER_ROSET_CONTENT( set, decl ) \
0125   decl \
0126   RTEMS_SECTION( ".rtemsroset." #set ".content" )
0127 
0128 #define RTEMS_LINKER_RWSET_DECLARE( set, type ) \
0129   extern RTEMS_LINKER_SET_ALIGN( type ) type RTEMS_LINKER_SET_BEGIN( set )[]; \
0130   extern RTEMS_LINKER_SET_ALIGN( type ) type RTEMS_LINKER_SET_END( set )[]
0131 
0132 #define RTEMS_LINKER_RWSET( set, type ) \
0133   RTEMS_LINKER_SET_ALIGN( type ) type RTEMS_LINKER_SET_BEGIN( set )[ 0 ] \
0134   RTEMS_SECTION( ".rtemsrwset." #set ".begin" ) RTEMS_USED; \
0135   RTEMS_LINKER_SET_ALIGN( type ) type RTEMS_LINKER_SET_END( set )[ 0 ] \
0136   RTEMS_SECTION( ".rtemsrwset." #set ".end" ) RTEMS_USED
0137 
0138 #define RTEMS_LINKER_RWSET_ITEM_ORDERED_DECLARE( set, type, item, order ) \
0139   extern RTEMS_LINKER_SET_ALIGN( type ) type _Linker_set_##set##_##item \
0140   RTEMS_SECTION( ".rtemsrwset." #set ".content.0." RTEMS_XSTRING( order ) )
0141 
0142 #define RTEMS_LINKER_RWSET_ITEM_DECLARE( set, type, item ) \
0143   extern RTEMS_LINKER_SET_ALIGN( type ) type _Linker_set_##set##_##item \
0144   RTEMS_SECTION( ".rtemsrwset." #set ".content.1" )
0145 
0146 /*
0147  * The .rtemsroset is here not a typo.  We must ensure that the references are
0148  * not a victim of the garbage collection of the linker.  Thus, we place them
0149  * in a dedicated area of the RTEMS read-only linker set section.
0150  */
0151 #define RTEMS_LINKER_RWSET_ITEM_REFERENCE( set, type, item ) \
0152   static RTEMS_LINKER_SET_ALIGN( type ) type            \
0153   * const _Set_reference_##set##_##item             \
0154   RTEMS_SECTION( ".rtemsroset.reference" ) RTEMS_USED = \
0155   &_Linker_set_##set##_##item
0156 
0157 #define RTEMS_LINKER_RWSET_ITEM_ORDERED( set, type, item, order ) \
0158   RTEMS_LINKER_SET_ALIGN( type ) type _Linker_set_##set##_##item \
0159   RTEMS_SECTION( ".rtemsrwset." #set ".content.0." RTEMS_XSTRING( order ) ) \
0160   RTEMS_USED
0161 
0162 #define RTEMS_LINKER_RWSET_ITEM( set, type, item ) \
0163   RTEMS_LINKER_SET_ALIGN( type ) type _Linker_set_##set##_##item \
0164   RTEMS_SECTION( ".rtemsrwset." #set ".content.1" ) RTEMS_USED
0165 
0166 #define RTEMS_LINKER_RWSET_CONTENT( set, decl ) \
0167   decl \
0168   RTEMS_SECTION( ".rtemsrwset." #set ".content" )
0169 
0170 #define RTEMS_LINKER_SET_SIZE( set ) \
0171   ( _Linker_set_Obfuscate( RTEMS_LINKER_SET_END( set ) ) \
0172     - _Linker_set_Obfuscate( RTEMS_LINKER_SET_BEGIN( set ) ) )
0173 
0174 #define RTEMS_LINKER_SET_ITEM_COUNT( set ) \
0175   ( RTEMS_LINKER_SET_SIZE( set ) \
0176     / sizeof( RTEMS_LINKER_SET_BEGIN( set )[ 0 ] ) )
0177 
0178 #define RTEMS_LINKER_SET_IS_EMPTY( set ) \
0179   ( RTEMS_LINKER_SET_SIZE( set ) == 0 )
0180 
0181 #define RTEMS_LINKER_SET_FOREACH( set, item ) \
0182   for ( \
0183     item = (void *) _Linker_set_Obfuscate( RTEMS_LINKER_SET_BEGIN( set ) ) ; \
0184     item != RTEMS_LINKER_SET_END( set ) ; \
0185     ++item \
0186   )
0187 
0188 /** @} */
0189 
0190 #ifdef __cplusplus
0191 }
0192 #endif /* __cplusplus */
0193 
0194 #endif /* _RTEMS_LINKERSET_H */