[build] Use weak definitions instead of weak declarations

This removes the need for inline safety wrappers, marginally reducing
the size penalty of weak functions, and works around an apparent
binutils bug that causes undefined weak symbols to not actually be
NULL when compiling with -fPIE (as EFI builds do).

A bug in versions of binutils prior to 2.16 (released in 2005) will
cause same-file weak definitions to not work with those
toolchains. Update the README to reflect our new dependency on
binutils >= 2.16.

Signed-off-by: Joshua Oreman <oremanj@rwcr.net>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
This commit is contained in:
Joshua Oreman
2010-05-26 17:52:44 -07:00
committed by Michael Brown
parent ba27168c2e
commit 2aad3fab23
12 changed files with 48 additions and 98 deletions

View File

@@ -179,41 +179,12 @@ REQUEST_EXPANDED ( CONFIG_SYMBOL );
/** 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; \
}
/** Declare a function as weak (use *before* the definition) */
#define __weak __attribute__ (( weak ))
#endif
/** @} */
/** @defgroup dbg Debugging infrastructure
* @{

View File

@@ -630,7 +630,7 @@ extern int start_pxebs ( struct job_interface *job, struct net_device *netdev,
* should look for such a packet and call store_cached_dhcpack() with
* it if it exists.
*/
__weak_decl ( void, get_cached_dhcpack, ( void ), (), );
extern void get_cached_dhcpack ( void );
extern void store_cached_dhcpack ( userptr_t data, size_t len );

View File

@@ -27,42 +27,11 @@ FILE_LICENCE ( GPL2_OR_LATER );
/** @file
*
* Definitions for general secured-network routines.
*
* Any function in this file which may be referenced by code which is
* not exclusive to encryption-enabled builds (e.g. sec80211_detect(),
* which is called by net80211_probe_step() to fill the net80211_wlan
* structure's security fields) must be declared as a weak symbol,
* using an inline interface similar to that used for
* sec80211_detect() below. This prevents secure network support from
* bloating general builds by any more than a few tiny hooks to call
* crypto functions when crypto structures are non-NULL.
*/
int _sec80211_detect ( struct io_buffer *iob,
enum net80211_security_proto *secprot,
enum net80211_crypto_alg *crypt )
__attribute__ (( weak ));
/**
* Inline safety wrapper for _sec80211_detect()
*
* @v iob I/O buffer containing beacon frame
* @ret secprot Security handshaking protocol used by network
* @ret crypt Cryptosystem used by network
* @ret rc Return status code
*
* This function transparently calls _sec80211_detect() if the file
* containing it was compiled in, or returns an error indication of
* @c -ENOTSUP if not.
*/
static inline int sec80211_detect ( struct io_buffer *iob,
enum net80211_security_proto *secprot,
enum net80211_crypto_alg *crypt ) {
if ( _sec80211_detect )
return _sec80211_detect ( iob, secprot, crypt );
return -ENOTSUP;
}
int sec80211_detect ( struct io_buffer *iob,
enum net80211_security_proto *secprot,
enum net80211_crypto_alg *crypt );
int sec80211_detect_ie ( int is_rsn, u8 *start, u8 *end,
enum net80211_security_proto *secprot,

View File

@@ -19,7 +19,6 @@ extern int boot_next_server_and_filename ( struct in_addr next_server,
const char *filename );
extern int boot_root_path ( const char *root_path );
extern int pxe_menu_boot ( struct net_device *netdev )
__attribute__ (( weak ));
extern int pxe_menu_boot ( struct net_device *netdev );
#endif /* _USR_AUTOBOOT_H */