Go to the source code of this file.
Defines | |
| #define | __attribute__(x) |
| #define | __table(type, name) ( type, name ) |
| Declare a linker table. | |
| #define | __table_type(table) __table_extract_type table |
| Get linker table data type. | |
| #define | __table_extract_type(type, name) type |
| #define | __table_name(table) __table_extract_name table |
| Get linker table name. | |
| #define | __table_extract_name(type, name) name |
| #define | __table_section(table, idx) ".tbl." __table_name ( table ) "." __table_str ( idx ) |
| Get linker table section name. | |
| #define | __table_str(x) #x |
| #define | __table_alignment(table) __alignof__ ( __table_type ( table ) ) |
| Get linker table alignment. | |
| #define | __table_entry(table, idx) |
| Declare a linker table entry. | |
| #define | __table_entries(table, idx) |
| Get start of linker table entries. | |
| #define | table_start(table) __table_entries ( table, 00 ) |
| Get start of linker table. | |
| #define | table_end(table) __table_entries ( table, 99 ) |
| Get end of linker table. | |
| #define | table_num_entries(table) |
| Get number of entries in linker table. | |
| #define | for_each_table_entry(pointer, table) |
| Iterate through all entries within a linker table. | |
| #define | for_each_table_entry_reverse(pointer, table) |
| Iterate through all entries within a linker table in reverse order. | |
| #define | ICC_ALIGN_HACK_FACTOR 128 |
Functions | |
| FILE_LICENCE (GPL2_OR_LATER) | |
Read ifdef considered harmful first for some background on the motivation for using linker tables.
This file provides macros for dealing with linker-generated tables of fixed-size symbols. We make fairly extensive use of these in order to avoid ifdef spaghetti and/or linker symbol pollution. For example, instead of having code such as
#ifdef CONSOLE_SERIAL serial_init(); #endif
we make serial.c generate an entry in the initialisation function table, and then have a function call_init_fns() that simply calls all functions present in this table. If and only if serial.o gets linked in, then its initialisation function will be called. We avoid linker symbol pollution (i.e. always dragging in serial.o just because of a call to serial_init()) and we also avoid ifdef spaghetti (having to conditionalise every reference to functions in serial.c).
The linker script takes care of assembling the tables for us. All our table sections have names of the format .tbl.NAME.NN where NAME designates the data structure stored in the table (e.g. init_fns) and NN is a two-digit decimal number used to impose an ordering upon the tables if required. NN=00 is reserved for the symbol indicating "table start", and NN=99 is reserved for the symbol indicating "table end".
As an example, suppose that we want to create a "frobnicator" feature framework, and allow for several independent modules to provide frobnicating services. Then we would create a frob.h header file containing e.g.
struct frobnicator { const char *name; // Name of the frobnicator void ( *frob ) ( void ); // The frobnicating function itself }; #define FROBNICATORS __table ( struct frobnicator, "frobnicators" ) #define __frobnicator __table_entry ( FROBNICATORS, 01 )
Any module providing frobnicating services would look something like
#include "frob.h" static void my_frob ( void ) { // Do my frobnicating ... } struct frob my_frobnicator __frobnicator = { .name = "my_frob", .frob = my_frob, };
The central frobnicator code (frob.c) would use the frobnicating modules as follows
#include "frob.h" // Call all linked-in frobnicators void frob_all ( void ) { struct frob *frob; for_each_table ( frob, FROBNICATORS ) { printf ( "Calling frobnicator \"%s\"\n", frob->name ); frob->frob (); } }
See init.h and init.c for a real-life example.
Definition in file tables.h.
| #define __table_type | ( | table | ) | __table_extract_type table |
| #define __table_name | ( | table | ) | __table_extract_name table |
| #define __table_section | ( | table, | |||
| idx | ) | ".tbl." __table_name ( table ) "." __table_str ( idx ) |
| #define __table_alignment | ( | table | ) | __alignof__ ( __table_type ( table ) ) |
| #define __table_entry | ( | table, | |||
| idx | ) |
Value:
__attribute__ (( __section__ ( __table_section ( table, idx ) ),\ __aligned__ ( __table_alignment ( table ) ) ))
| table | Linker table | |
| idx | Sub-table index |
#define FROBNICATORS __table ( struct frobnicator, "frobnicators" ) #define __frobnicator __table_entry ( FROBNICATORS, 01 ) struct frobnicator my_frob __frobnicator = { ... };
| #define __table_entries | ( | table, | |||
| idx | ) |
Value:
( { \
static __table_type ( table ) __table_entries[0] \
__table_entry ( table, idx ); \
__table_entries; } )
| table | Linker table | |
| idx | Sub-table index |
| entries | Start of entries |
| #define table_start | ( | table | ) | __table_entries ( table, 00 ) |
Get start of linker table.
| table | Linker table |
| start | Start of linker table |
#define FROBNICATORS __table ( struct frobnicator, "frobnicators" ) struct frobnicator *frobs = table_start ( FROBNICATORS );
Definition at line 270 of file tables.h.
Referenced by dhcp_create_request(), init_setting_index(), resolv(), and sec80211_detect_ie().
| #define table_end | ( | table | ) | __table_entries ( table, 99 ) |
Get end of linker table.
| table | Linker table |
| end | End of linker table |
#define FROBNICATORS __table ( struct frobnicator, "frobnicators" ) struct frobnicator *frobs_end = table_end ( FROBNICATORS );
Definition at line 288 of file tables.h.
Referenced by resolv_mux_done(), and sec80211_detect_ie().
| #define table_num_entries | ( | table | ) |
Value:
( ( unsigned int ) ( table_end ( table ) - \ table_start ( table ) ) )
| table | Linker table |
| num_entries | Number of entries in linker table |
#define FROBNICATORS __table ( struct frobnicator, "frobnicators" ) unsigned int num_frobs = table_num_entries ( FROBNICATORS );
Definition at line 307 of file tables.h.
Referenced by dhcp_create_request().
| #define for_each_table_entry | ( | pointer, | |||
| table | ) |
Value:
for ( pointer = table_start ( table ) ; \ pointer < table_end ( table ) ; \ pointer++ )
| pointer | Entry pointer | |
| table | Linker table |
#define FROBNICATORS __table ( struct frobnicator, "frobnicators" ) struct frobnicator *frob; for_each_table_entry ( frob, FROBNICATORS ) { ... }
Definition at line 332 of file tables.h.
Referenced by apply_settings(), arp_find_protocol(), boot_root_path(), eapol_rx(), efi_init(), eisa_probe(), execv(), find_error(), find_gdb_transport(), find_setting(), find_setting_type(), has_input(), help_exec(), ib_mi_handle(), image_autoload(), init_processes(), initialise(), isabus_probe(), isapnp_probe(), main(), mca_probe(), net80211_prepare_assoc(), net_rx(), pci_probe(), probe_devices(), putchar(), rtl818x_probe(), sec80211_install(), startup(), tcpip_rx(), tcpip_tx(), wpa_find_cryptosystem(), wpa_find_kie(), xfer_open_socket(), and xfer_open_uri().
| #define for_each_table_entry_reverse | ( | pointer, | |||
| table | ) |
Value:
for ( pointer = ( table_end ( table ) - 1 ) ; \ pointer >= table_start ( table ) ; \ pointer-- )
| pointer | Entry pointer | |
| table | Linker table |
#define FROBNICATORS __table ( struct frobnicator, "frobnicators" ) struct frobnicator *frob; for_each_table_entry_reverse ( frob, FROBNICATORS ) { ... }
Definition at line 358 of file tables.h.
Referenced by shutdown().
| FILE_LICENCE | ( | GPL2_OR_LATER | ) |
1.5.7.1