From 49d6f5700561be091b2b25bb7641708333e4911d Mon Sep 17 00:00:00 2001 From: Joshua Oreman Date: Wed, 18 Aug 2010 16:37:22 -0700 Subject: [PATCH] [compiler] Prevent empty weak function stubs from being removed Even with the noinline specifier added by commit 1a260f8, gcc may skip calls to non-inlinable functions that it knows have no side effects. This caused the get_cached_dhcpack() call in start_dhcp(), the weak stub of which has no code in its body, to be removed, preventing cached DHCP from working. Fix by adding a __keepme macro to compiler.h expanding to asm(""), as recommended by gcc's info page, and using it in the weak stub for get_cached_dhcpack(). Reported-by: Aaron Brooks Tested-by: Aaron Brooks Signed-off-by: Joshua Oreman Signed-off-by: Michael Brown --- src/include/compiler.h | 8 ++++++++ src/net/udp/dhcp.c | 2 +- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/src/include/compiler.h b/src/include/compiler.h index 16165b36..738655af 100644 --- a/src/include/compiler.h +++ b/src/include/compiler.h @@ -191,6 +191,14 @@ REQUEST_EXPANDED ( CONFIG_SYMBOL ); */ #define __weak __attribute__ (( weak, noinline )) +/** Prevent a function from being optimized away without inlining + * + * Calls to functions with void return type that contain no code in their body + * may be removed by gcc's optimizer even when inlining is inhibited. Placing + * this macro in the body of the function prevents that from occurring. + */ +#define __keepme asm(""); + #endif /** @defgroup dbg Debugging infrastructure diff --git a/src/net/udp/dhcp.c b/src/net/udp/dhcp.c index fb62bef5..77d46545 100644 --- a/src/net/udp/dhcp.c +++ b/src/net/udp/dhcp.c @@ -1389,7 +1389,7 @@ static struct sockaddr dhcp_peer = { /** * Get cached DHCPACK where none exists */ -__weak void get_cached_dhcpack ( void ) {} +__weak void get_cached_dhcpack ( void ) { __keepme } /** * Start DHCP state machine on a network device