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 <aaron@brooks1.net>
Tested-by: Aaron Brooks <aaron@brooks1.net>
Signed-off-by: Joshua Oreman <oremanj@rwcr.net>
* used). This results in the non-weak symbol never being used, so explicitly
* mark the function as noinline to prevent inlining.
*/
-#define __weak __attribute__ (( weak )) __attribute (( noinline ))
+#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
/**
* 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