diff options
Diffstat (limited to 'gpxe/src/include/compiler.h')
-rw-r--r-- | gpxe/src/include/compiler.h | 650 |
1 files changed, 0 insertions, 650 deletions
diff --git a/gpxe/src/include/compiler.h b/gpxe/src/include/compiler.h deleted file mode 100644 index ea81fc89..00000000 --- a/gpxe/src/include/compiler.h +++ /dev/null @@ -1,650 +0,0 @@ -#ifndef COMPILER_H -#define COMPILER_H - -/* - * Doxygen can't cope with some of the more esoteric areas of C, so we - * make its life simpler. - * - */ -#ifdef DOXYGEN -#define __attribute__(x) -#endif - -/** @file - * - * Global compiler definitions. - * - * This file is implicitly included by every @c .c file in Etherboot. - * It defines global macros such as DBG(). - * - * We arrange for each object to export the symbol @c obj_OBJECT - * (where @c OBJECT is the object name, e.g. @c rtl8139) as a global - * symbol, so that the linker can drag in selected object files from - * the library using <tt> -u obj_OBJECT </tt>. - * - */ - -/* Force visibility of all symbols to "hidden", i.e. inform gcc that - * all symbol references resolve strictly within our final binary. - * This avoids unnecessary PLT/GOT entries on x86_64. - * - * This is a stronger claim than specifying "-fvisibility=hidden", - * since it also affects symbols marked with "extern". - */ -#ifndef ASSEMBLY -#if __GNUC__ >= 4 -#pragma GCC visibility push(hidden) -#endif -#endif /* ASSEMBLY */ - -#undef _S1 -#undef _S2 -#undef _C1 -#undef _C2 - -/** Concatenate non-expanded arguments */ -#define _C1( x, y ) x ## y -/** Concatenate expanded arguments */ -#define _C2( x, y ) _C1 ( x, y ) - -/** Stringify non-expanded argument */ -#define _S1( x ) #x -/** Stringify expanded argument */ -#define _S2( x ) _S1 ( x ) - -/** - * @defgroup symmacros Macros to provide or require explicit symbols - * @{ - */ - -/** Provide a symbol within this object file */ -#ifdef ASSEMBLY -#define PROVIDE_SYMBOL( _sym ) \ - .globl _sym ; \ - .comm _sym, 0 -#else /* ASSEMBLY */ -#define PROVIDE_SYMBOL( _sym ) \ - char _sym[0] -#endif /* ASSEMBLY */ - -/** Require a symbol within this object file - * - * The symbol is referenced by a relocation in a discarded section, so - * if it is not available at link time the link will fail. - */ -#ifdef ASSEMBLY -#define REQUIRE_SYMBOL( _sym ) \ - .section ".discard", "a", @progbits ; \ - .extern _sym ; \ - .long _sym ; \ - .previous -#else /* ASSEMBLY */ -#define REQUIRE_SYMBOL( _sym ) \ - extern char _sym; \ - static char * _C2 ( _C2 ( __require_, _sym ), _C2 ( _, __LINE__ ) ) \ - __attribute__ (( section ( ".discard" ), used )) \ - = &_sym -#endif - -/** Request that a symbol be available at runtime - * - * The requested symbol is entered as undefined into the symbol table - * for this object, so the linker will pull in other object files as - * necessary to satisfy the reference. However, the undefined symbol - * is not referenced in any relocations, so the link can still succeed - * if no file contains it. - * - * A symbol passed to this macro may not be referenced anywhere - * else in the file. If you want to do that, see IMPORT_SYMBOL(). - */ -#ifdef ASSEMBLY -#define REQUEST_SYMBOL( _sym ) \ - .equ __need_ ## _sym, _sym -#else /* ASSEMBLY */ -#define REQUEST_SYMBOL( _sym ) \ - __asm__ ( ".equ\t__need_" #_sym ", " #_sym ) -#endif /* ASSEMBLY */ - -/** Set up a symbol to be usable in another file by IMPORT_SYMBOL() - * - * The symbol must already be marked as global. - */ -#define EXPORT_SYMBOL( _sym ) PROVIDE_SYMBOL ( __export_ ## _sym ) - -/** Make a symbol usable to this file if available at link time - * - * If no file passed to the linker contains the symbol, it will have - * @c NULL value to future uses. Keep in mind that the symbol value is - * really the @e address of a variable or function; see the code - * snippet below. - * - * In C using IMPORT_SYMBOL, you must specify the declaration as the - * second argument, for instance - * - * @code - * IMPORT_SYMBOL ( my_func, int my_func ( int arg ) ); - * IMPORT_SYMBOL ( my_var, int my_var ); - * - * void use_imports ( void ) { - * if ( my_func && &my_var ) - * my_var = my_func ( my_var ); - * } - * @endcode - * - * GCC considers a weak declaration to override a strong one no matter - * which comes first, so it is safe to include a header file declaring - * the imported symbol normally, but providing the declaration to - * IMPORT_SYMBOL is still required. - * - * If no EXPORT_SYMBOL declaration exists for the imported symbol in - * another file, the behavior will be most likely be identical to that - * for an unavailable symbol. - */ -#ifdef ASSEMBLY -#define IMPORT_SYMBOL( _sym ) \ - REQUEST_SYMBOL ( __export_ ## _sym ) ; \ - .weak _sym -#else /* ASSEMBLY */ -#define IMPORT_SYMBOL( _sym, _decl ) \ - REQUEST_SYMBOL ( __export_ ## _sym ) ; \ - extern _decl __attribute__ (( weak )) -#endif - -/** @} */ - -/** - * @defgroup objmacros Macros to provide or require explicit objects - * @{ - */ - -#define PREFIX_OBJECT( _prefix ) _C2 ( _prefix, OBJECT ) -#define OBJECT_SYMBOL PREFIX_OBJECT ( obj_ ) -#define REQUEST_EXPANDED( _sym ) REQUEST_SYMBOL ( _sym ) -#define CONFIG_SYMBOL PREFIX_OBJECT ( obj_config_ ) - -/** Always provide the symbol for the current object (defined by -DOBJECT) */ -PROVIDE_SYMBOL ( OBJECT_SYMBOL ); - -/** Pull in an object-specific configuration file if available */ -REQUEST_EXPANDED ( CONFIG_SYMBOL ); - -/** Explicitly require another object */ -#define REQUIRE_OBJECT( _obj ) REQUIRE_SYMBOL ( obj_ ## _obj ) - -/** Pull in another object if it exists */ -#define REQUEST_OBJECT( _obj ) REQUEST_SYMBOL ( obj_ ## _obj ) - -/** @} */ - -/** Select file identifier for errno.h (if used) */ -#define ERRFILE PREFIX_OBJECT ( ERRFILE_ ) - -/** - * @defgroup weakmacros Macros to manage weak symbol definitions - * - * Weak symbols allow one to reference a function in another file - * without necessarily requiring that file to be linked in. In their - * native form, the function will be @c NULL if its file is not linked - * in; these macros provide an inline wrapper that returns an - * appropriate error indication or default value. - * - * @{ - */ -#ifndef ASSEMBLY - -/** Mangle @a name into its weakly-referenced implementation */ -#define __weak_impl( name ) _w_ ## name - -/** - * Declare a weak function with inline safety wrapper - * - * @v ret Return type of weak function - * @v name Name of function to expose - * @v proto Parenthesized list of arguments with types - * @v args Parenthesized list of argument names - * @v dfl Value to return if weak function is not available - */ -#define __weak_decl( ret, name, proto, args, dfl ) \ - ret __weak_impl( name ) proto __attribute__ (( weak )); \ - static inline ret name proto { \ - if ( __weak_impl( name ) ) \ - return __weak_impl( name ) args; \ - return dfl; \ - } - -#endif -/** @} */ - -/** @defgroup dbg Debugging infrastructure - * @{ - */ -#ifndef ASSEMBLY - -/** @def DBG - * - * Print a debugging message. - * - * The debug level is set at build time by specifying the @c DEBUG= - * parameter on the @c make command line. For example, to enable - * debugging for the PCI bus functions (in pci.c) in a @c .dsk image - * for the @c rtl8139 card, you could use the command line - * - * @code - * - * make bin/rtl8139.dsk DEBUG=pci - * - * @endcode - * - * This will enable the debugging statements (DBG()) in pci.c. If - * debugging is not enabled, DBG() statements will be ignored. - * - * You can enable debugging in several objects simultaneously by - * separating them with commas, as in - * - * @code - * - * make bin/rtl8139.dsk DEBUG=pci,buffer,heap - * - * @endcode - * - * You can increase the debugging level for an object by specifying it - * with @c :N, where @c N is the level, as in - * - * @code - * - * make bin/rtl8139.dsk DEBUG=pci,buffer:2,heap - * - * @endcode - * - * which would enable debugging for the PCI, buffer-handling and - * heap-allocation code, with the buffer-handling code at level 2. - * - */ - -/* - * If debug_OBJECT is set to a true value, the macro DBG(...) will - * expand to printf(...) when compiling OBJECT, and the symbol - * DEBUG_LEVEL will be inserted into the object file. - * - */ -#define DEBUG_SYMBOL PREFIX_OBJECT ( debug_ ) - -/** printf() for debugging - * - * This function exists so that the DBG() macros can expand to - * printf() calls without dragging the printf() prototype into scope. - * - * As far as the compiler is concerned, dbg_printf() and printf() are - * completely unrelated calls; it's only at the assembly stage that - * references to the dbg_printf symbol are collapsed into references - * to the printf symbol. - */ -extern int __attribute__ (( format ( printf, 1, 2 ) )) -dbg_printf ( const char *fmt, ... ) asm ( "printf" ); - -extern void dbg_autocolourise ( unsigned long id ); -extern void dbg_decolourise ( void ); -extern void dbg_hex_dump_da ( unsigned long dispaddr, - const void *data, unsigned long len ); - -#if DEBUG_SYMBOL -#define DBGLVL_MAX DEBUG_SYMBOL -#else -#define DBGLVL_MAX 0 -#endif - -/* Allow for selective disabling of enabled debug levels */ -#if DBGLVL_MAX -int __debug_disable; -#define DBGLVL ( DBGLVL_MAX & ~__debug_disable ) -#define DBG_DISABLE( level ) do { \ - __debug_disable |= ( (level) & DBGLVL_MAX ); \ - } while ( 0 ) -#define DBG_ENABLE( level ) do { \ - __debug_disable &= ~( (level) & DBGLVL_MAX ); \ - } while ( 0 ) -#else -#define DBGLVL 0 -#define DBG_DISABLE( level ) do { } while ( 0 ) -#define DBG_ENABLE( level ) do { } while ( 0 ) -#endif - -#define DBGLVL_LOG 1 -#define DBG_LOG ( DBGLVL & DBGLVL_LOG ) -#define DBGLVL_EXTRA 2 -#define DBG_EXTRA ( DBGLVL & DBGLVL_EXTRA ) -#define DBGLVL_PROFILE 4 -#define DBG_PROFILE ( DBGLVL & DBGLVL_PROFILE ) -#define DBGLVL_IO 8 -#define DBG_IO ( DBGLVL & DBGLVL_IO ) - -/** - * Print debugging message if we are at a certain debug level - * - * @v level Debug level - * @v ... printf() argument list - */ -#define DBG_IF( level, ... ) do { \ - if ( DBG_ ## level ) { \ - dbg_printf ( __VA_ARGS__ ); \ - } \ - } while ( 0 ) - -/** - * Print a hex dump if we are at a certain debug level - * - * @v level Debug level - * @v dispaddr Display address - * @v data Data to print - * @v len Length of data - */ -#define DBG_HDA_IF( level, dispaddr, data, len ) do { \ - if ( DBG_ ## level ) { \ - union { \ - unsigned long ul; \ - typeof ( dispaddr ) raw; \ - } da; \ - da.raw = dispaddr; \ - dbg_hex_dump_da ( da.ul, data, len ); \ - } \ - } while ( 0 ) - -/** - * Print a hex dump if we are at a certain debug level - * - * @v level Debug level - * @v data Data to print - * @v len Length of data - */ -#define DBG_HD_IF( level, data, len ) do { \ - const void *_data = data; \ - DBG_HDA_IF ( level, _data, _data, len ); \ - } while ( 0 ) - -/** - * Select colour for debug messages if we are at a certain debug level - * - * @v level Debug level - * @v id Message stream ID - */ -#define DBG_AC_IF( level, id ) do { \ - if ( DBG_ ## level ) { \ - union { \ - unsigned long ul; \ - typeof ( id ) raw; \ - } dbg_stream; \ - dbg_stream.raw = id; \ - dbg_autocolourise ( dbg_stream.ul ); \ - } \ - } while ( 0 ) - -/** - * Revert colour for debug messages if we are at a certain debug level - * - * @v level Debug level - */ -#define DBG_DC_IF( level ) do { \ - if ( DBG_ ## level ) { \ - dbg_decolourise(); \ - } \ - } while ( 0 ) - -/* Autocolourising versions of the DBGxxx_IF() macros */ - -#define DBGC_IF( level, id, ... ) do { \ - DBG_AC_IF ( level, id ); \ - DBG_IF ( level, __VA_ARGS__ ); \ - DBG_DC_IF ( level ); \ - } while ( 0 ) - -#define DBGC_HDA_IF( level, id, ... ) do { \ - DBG_AC_IF ( level, id ); \ - DBG_HDA_IF ( level, __VA_ARGS__ ); \ - DBG_DC_IF ( level ); \ - } while ( 0 ) - -#define DBGC_HD_IF( level, id, ... ) do { \ - DBG_AC_IF ( level, id ); \ - DBG_HD_IF ( level, __VA_ARGS__ ); \ - DBG_DC_IF ( level ); \ - } while ( 0 ) - -/* Versions of the DBGxxx_IF() macros that imply DBGxxx_IF( LOG, ... )*/ - -#define DBG( ... ) DBG_IF ( LOG, __VA_ARGS__ ) -#define DBG_HDA( ... ) DBG_HDA_IF ( LOG, __VA_ARGS__ ) -#define DBG_HD( ... ) DBG_HD_IF ( LOG, __VA_ARGS__ ) -#define DBGC( ... ) DBGC_IF ( LOG, __VA_ARGS__ ) -#define DBGC_HDA( ... ) DBGC_HDA_IF ( LOG, __VA_ARGS__ ) -#define DBGC_HD( ... ) DBGC_HD_IF ( LOG, __VA_ARGS__ ) - -/* Versions of the DBGxxx_IF() macros that imply DBGxxx_IF( EXTRA, ... )*/ - -#define DBG2( ... ) DBG_IF ( EXTRA, __VA_ARGS__ ) -#define DBG2_HDA( ... ) DBG_HDA_IF ( EXTRA, __VA_ARGS__ ) -#define DBG2_HD( ... ) DBG_HD_IF ( EXTRA, __VA_ARGS__ ) -#define DBGC2( ... ) DBGC_IF ( EXTRA, __VA_ARGS__ ) -#define DBGC2_HDA( ... ) DBGC_HDA_IF ( EXTRA, __VA_ARGS__ ) -#define DBGC2_HD( ... ) DBGC_HD_IF ( EXTRA, __VA_ARGS__ ) - -/* Versions of the DBGxxx_IF() macros that imply DBGxxx_IF( PROFILE, ... )*/ - -#define DBGP( ... ) DBG_IF ( PROFILE, __VA_ARGS__ ) -#define DBGP_HDA( ... ) DBG_HDA_IF ( PROFILE, __VA_ARGS__ ) -#define DBGP_HD( ... ) DBG_HD_IF ( PROFILE, __VA_ARGS__ ) -#define DBGCP( ... ) DBGC_IF ( PROFILE, __VA_ARGS__ ) -#define DBGCP_HDA( ... ) DBGC_HDA_IF ( PROFILE, __VA_ARGS__ ) -#define DBGCP_HD( ... ) DBGC_HD_IF ( PROFILE, __VA_ARGS__ ) - -/* Versions of the DBGxxx_IF() macros that imply DBGxxx_IF( IO, ... )*/ - -#define DBGIO( ... ) DBG_IF ( IO, __VA_ARGS__ ) -#define DBGIO_HDA( ... ) DBG_HDA_IF ( IO, __VA_ARGS__ ) -#define DBGIO_HD( ... ) DBG_HD_IF ( IO, __VA_ARGS__ ) -#define DBGCIO( ... ) DBGC_IF ( IO, __VA_ARGS__ ) -#define DBGCIO_HDA( ... ) DBGC_HDA_IF ( IO, __VA_ARGS__ ) -#define DBGCIO_HD( ... ) DBGC_HD_IF ( IO, __VA_ARGS__ ) - - -#if DEBUG_SYMBOL == 0 -#define NDEBUG -#endif - -#endif /* ASSEMBLY */ -/** @} */ - -/** @defgroup attrs Miscellaneous attributes - * @{ - */ -#ifndef ASSEMBLY - -/** Declare a data structure as packed. */ -#define PACKED __attribute__ (( packed )) - -/** Declare a variable or data structure as unused. */ -#define __unused __attribute__ (( unused )) - -/** - * Declare a function as pure - i.e. without side effects - */ -#define __pure __attribute__ (( pure )) - -/** - * Declare a function as const - i.e. it does not access global memory - * (including dereferencing pointers passed to it) at all. - * Must also not call any non-const functions. - */ -#define __const __attribute__ (( const )) - -/** - * Declare a function's pointer parameters as non-null - i.e. force - * compiler to check pointers at compile time and enable possible - * optimizations based on that fact - */ -#define __nonnull __attribute__ (( nonnull )) - -/** - * Declare a pointer returned by a function as a unique memory address - * as returned by malloc-type functions. - */ -#define __malloc __attribute__ (( malloc )) - -/** - * Declare a function as used. - * - * Necessary only if the function is called only from assembler code. - */ -#define __used __attribute__ (( used )) - -/** Declare a data structure to be aligned with 16-byte alignment */ -#define __aligned __attribute__ (( aligned ( 16 ) )) - -/** Declare a function to be always inline */ -#define __always_inline __attribute__ (( always_inline )) - -/** - * Shared data. - * - * To save space in the binary when multiple-driver images are - * compiled, uninitialised data areas can be shared between drivers. - * This will typically be used to share statically-allocated receive - * and transmit buffers between drivers. - * - * Use as e.g. - * - * @code - * - * struct { - * char rx_buf[NUM_RX_BUF][RX_BUF_SIZE]; - * char tx_buf[TX_BUF_SIZE]; - * } my_static_data __shared; - * - * @endcode - * - */ -#define __shared __asm__ ( "_shared_bss" ) __aligned - -#endif /* ASSEMBLY */ -/** @} */ - -/** - * Optimisation barrier - */ -#ifndef ASSEMBLY -#define barrier() __asm__ __volatile__ ( "" : : : "memory" ) -#endif /* ASSEMBLY */ - -/** - * @defgroup licences Licence declarations - * - * For reasons that are partly historical, various different files - * within the gPXE codebase have differing licences. - * - * @{ - */ - -/** Declare a file as being in the public domain - * - * This licence declaration is applicable when a file states itself to - * be in the public domain. - */ -#define FILE_LICENCE_PUBLIC_DOMAIN \ - PROVIDE_SYMBOL ( __licence_public_domain ) - -/** Declare a file as being under version 2 (or later) of the GNU GPL - * - * This licence declaration is applicable when a file states itself to - * be licensed under the GNU GPL; "either version 2 of the License, or - * (at your option) any later version". - */ -#define FILE_LICENCE_GPL2_OR_LATER \ - PROVIDE_SYMBOL ( __licence_gpl2_or_later ) - -/** Declare a file as being under version 2 of the GNU GPL - * - * This licence declaration is applicable when a file states itself to - * be licensed under version 2 of the GPL, and does not include the - * "or, at your option, any later version" clause. - */ -#define FILE_LICENCE_GPL2_ONLY \ - PROVIDE_SYMBOL ( __licence_gpl2_only ) - -/** Declare a file as being under any version of the GNU GPL - * - * This licence declaration is applicable when a file states itself to - * be licensed under the GPL, but does not specify a version. - * - * According to section 9 of the GPLv2, "If the Program does not - * specify a version number of this License, you may choose any - * version ever published by the Free Software Foundation". - */ -#define FILE_LICENCE_GPL_ANY \ - PROVIDE_SYMBOL ( __licence_gpl_any ) - -/** Declare a file as being under the three-clause BSD licence - * - * This licence declaration is applicable when a file states itself to - * be licensed under terms allowing redistribution in source and - * binary forms (with or without modification) provided that: - * - * redistributions of source code retain the copyright notice, - * list of conditions and any attached disclaimers - * - * redistributions in binary form reproduce the copyright notice, - * list of conditions and any attached disclaimers in the - * documentation and/or other materials provided with the - * distribution - * - * the name of the author is not used to endorse or promote - * products derived from the software without specific prior - * written permission - * - * It is not necessary for the file to explicitly state that it is - * under a "BSD" licence; only that the licensing terms be - * functionally equivalent to the standard three-clause BSD licence. - */ -#define FILE_LICENCE_BSD3 \ - PROVIDE_SYMBOL ( __licence_bsd3 ) - -/** Declare a file as being under the two-clause BSD licence - * - * This licence declaration is applicable when a file states itself to - * be licensed under terms allowing redistribution in source and - * binary forms (with or without modification) provided that: - * - * redistributions of source code retain the copyright notice, - * list of conditions and any attached disclaimers - * - * redistributions in binary form reproduce the copyright notice, - * list of conditions and any attached disclaimers in the - * documentation and/or other materials provided with the - * distribution - * - * It is not necessary for the file to explicitly state that it is - * under a "BSD" licence; only that the licensing terms be - * functionally equivalent to the standard two-clause BSD licence. - */ -#define FILE_LICENCE_BSD2 \ - PROVIDE_SYMBOL ( __licence_bsd2 ) - -/** Declare a file as being under the one-clause MIT-style licence - * - * This licence declaration is applicable when a file states itself to - * be licensed under terms allowing redistribution for any purpose - * with or without fee, provided that the copyright notice and - * permission notice appear in all copies. - */ -#define FILE_LICENCE_MIT \ - PROVIDE_SYMBOL ( __licence_mit ) - -/** Declare a particular licence as applying to a file */ -#define FILE_LICENCE( _licence ) FILE_LICENCE_ ## _licence - -/** @} */ - -/* This file itself is under GPLv2-or-later */ -FILE_LICENCE ( GPL2_OR_LATER ); - -#include <bits/compiler.h> - -#endif /* COMPILER_H */ |