Переглянути джерело

[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 <aaron@brooks1.net>
Tested-by: Aaron Brooks <aaron@brooks1.net>
Signed-off-by: Joshua Oreman <oremanj@rwcr.net>
Signed-off-by: Michael Brown <mcb30@ipxe.org>
tags/v1.20.1
Joshua Oreman 14 роки тому
джерело
коміт
49d6f57005
2 змінених файлів з 9 додано та 1 видалено
  1. 8
    0
      src/include/compiler.h
  2. 1
    1
      src/net/udp/dhcp.c

+ 8
- 0
src/include/compiler.h Переглянути файл

@@ -191,6 +191,14 @@ REQUEST_EXPANDED ( CONFIG_SYMBOL );
191 191
  */
192 192
 #define __weak		__attribute__ (( weak, noinline ))
193 193
 
194
+/** Prevent a function from being optimized away without inlining
195
+ *
196
+ * Calls to functions with void return type that contain no code in their body
197
+ * may be removed by gcc's optimizer even when inlining is inhibited. Placing
198
+ * this macro in the body of the function prevents that from occurring.
199
+ */
200
+#define __keepme	asm("");
201
+
194 202
 #endif
195 203
 
196 204
 /** @defgroup dbg Debugging infrastructure

+ 1
- 1
src/net/udp/dhcp.c Переглянути файл

@@ -1389,7 +1389,7 @@ static struct sockaddr dhcp_peer = {
1389 1389
 /**
1390 1390
  * Get cached DHCPACK where none exists
1391 1391
  */
1392
-__weak void get_cached_dhcpack ( void ) {}
1392
+__weak void get_cached_dhcpack ( void ) { __keepme }
1393 1393
 
1394 1394
 /**
1395 1395
  * Start DHCP state machine on a network device

Завантаження…
Відмінити
Зберегти