summaryrefslogtreecommitdiffstats
path: root/src/include/compiler.h
diff options
context:
space:
mode:
authorMichael Brown2015-03-04 19:48:19 +0100
committerMichael Brown2015-03-05 01:59:38 +0100
commitfbc4ba4b4ed13cc86cb8fdea0bac6c3be0164ed5 (patch)
treea0c504e297806aa88e89a04e694333a7c5172757 /src/include/compiler.h
parent[build] Use REQUIRE_OBJECT() to drag in per-object configuration (diff)
downloadipxe-fbc4ba4b4ed13cc86cb8fdea0bac6c3be0164ed5.tar.gz
ipxe-fbc4ba4b4ed13cc86cb8fdea0bac6c3be0164ed5.tar.xz
ipxe-fbc4ba4b4ed13cc86cb8fdea0bac6c3be0164ed5.zip
[build] Fix the REQUIRE_SYMBOL mechanism
At some point in the past few years, binutils became more aggressive at removing unused symbols. To function as a symbol requirement, a relocation record must now be in a section marked with @progbits and must not be in a section which gets discarded during the link (either via --gc-sections or via /DISCARD/). Update REQUIRE_SYMBOL() to generate relocation records meeting these criteria. To minimise the impact upon the final binary size, we use existing symbols (specified via the REQUIRING_SYMBOL() macro) as the relocation targets where possible. We use R_386_NONE or R_X86_64_NONE relocation types to prevent any actual unwanted relocation taking place. Where no suitable symbol exists for REQUIRING_SYMBOL() (such as in config.c), the macro PROVIDE_REQUIRING_SYMBOL() can be used to generate a one-byte-long symbol to act as the relocation target. If there are versions of binutils for which this approach fails, then the fallback will probably involve killing off REQUEST_SYMBOL(), redefining REQUIRE_SYMBOL() to use the current definition of REQUEST_SYMBOL(), and postprocessing the linked ELF file with something along the lines of "nm -u | wc -l" to check that there are no undefined symbols remaining. Signed-off-by: Michael Brown <mcb30@ipxe.org>
Diffstat (limited to 'src/include/compiler.h')
-rw-r--r--src/include/compiler.h149
1 files changed, 107 insertions, 42 deletions
diff --git a/src/include/compiler.h b/src/include/compiler.h
index f877ebce..ca82f952 100644
--- a/src/include/compiler.h
+++ b/src/include/compiler.h
@@ -57,54 +57,101 @@
* @{
*/
-/** Provide a symbol within this object file */
+/**
+ * Provide a symbol within this object file
+ *
+ * @v symbol Symbol name
+ */
#ifdef ASSEMBLY
-#define PROVIDE_SYMBOL( _sym ) \
- .section ".provided", "a", @nobits ; \
- .hidden _sym ; \
- .globl _sym ; \
- _sym: ; \
+#define PROVIDE_SYMBOL( symbol ) \
+ .section ".provided", "a", @nobits ; \
+ .hidden symbol ; \
+ .globl symbol ; \
+ symbol: ; \
.previous
-#else /* ASSEMBLY */
-#define PROVIDE_SYMBOL( _sym ) \
- char _sym[0] \
+#else
+#define PROVIDE_SYMBOL( symbol ) \
+ char symbol[0] \
__attribute__ (( section ( ".provided" ) ))
-#endif /* ASSEMBLY */
+#endif
-/** Require a symbol within this object file
+/**
+ * Request a symbol
+ *
+ * @v symbol Symbol name
*
- * The symbol is referenced by a relocation in a discarded section, so
- * if it is not available at link time the link will fail.
+ * Request a symbol to be included within the link. If the symbol
+ * cannot be found, the link will succeed anyway.
*/
#ifdef ASSEMBLY
-#define REQUIRE_SYMBOL( _sym ) \
- .section ".discard", "a", @progbits ; \
- .extern _sym ; \
- .long _sym ; \
- .previous
-#else /* ASSEMBLY */
-#define REQUIRE_SYMBOL( _sym ) \
- extern char _sym; \
- static char * _C2 ( _C2 ( __require_, _sym ), _C2 ( _, __LINE__ ) ) \
- __attribute__ (( section ( ".discard" ), used )) \
- = &_sym
+#define REQUEST_SYMBOL( symbol ) \
+ .equ __request_ ## symbol, symbol
+#else
+#define REQUEST_SYMBOL( symbol ) \
+ __asm__ ( ".equ __request_" #symbol ", " #symbol )
#endif
-/** Request that a symbol be available at runtime
+/**
+ * Require a symbol
*
- * The requested symbol is entered as undefined into the symbol table
- * for this object, so the linker will pull in other object files as
- * necessary to satisfy the reference. However, the undefined symbol
- * is not referenced in any relocations, so the link can still succeed
- * if no file contains it.
+ * @v symbol Symbol name
+ *
+ * Require a symbol to be included within the link. If the symbol
+ * cannot be found, the link will fail.
+ *
+ * To use this macro within a file, you must also specify the file's
+ * "requiring symbol" using the REQUIRING_SYMBOL() or
+ * PROVIDE_REQUIRING_SYMBOL() macros.
*/
#ifdef ASSEMBLY
-#define REQUEST_SYMBOL( _sym ) \
- .equ __need_ ## _sym, _sym
-#else /* ASSEMBLY */
-#define REQUEST_SYMBOL( _sym ) \
- __asm__ ( ".equ\t__need_" #_sym ", " #_sym )
-#endif /* ASSEMBLY */
+#define REQUIRE_SYMBOL( symbol ) \
+ .reloc __requiring_symbol__, RELOC_TYPE_NONE, symbol
+#else
+#define REQUIRE_SYMBOL( symbol ) \
+ __asm__ ( ".reloc __requiring_symbol__, " \
+ _S2 ( RELOC_TYPE_NONE ) ", " #symbol )
+#endif
+
+/**
+ * Specify the file's requiring symbol
+ *
+ * @v symbol Symbol name
+ *
+ * REQUIRE_SYMBOL() works by defining a dummy relocation record
+ * against a nominated "requiring symbol". The presence of the
+ * nominated requiring symbol will drag in all of the symbols
+ * specified using REQUIRE_SYMBOL().
+ */
+#ifdef ASSEMBLY
+#define REQUIRING_SYMBOL( symbol ) \
+ .equ __requiring_symbol__, symbol
+#else
+#define REQUIRING_SYMBOL( symbol ) \
+ __asm__ ( ".equ __requiring_symbol__, " #symbol )
+#endif
+
+/**
+ * Provide a file's requiring symbol
+ *
+ * If the file contains no symbols that can be used as the requiring
+ * symbol, you can provide a dummy one-byte-long symbol using
+ * PROVIDE_REQUIRING_SYMBOL().
+ */
+#ifdef ASSEMBLY
+#define PROVIDE_REQUIRING_SYMBOL() \
+ .section ".tbl.requiring_symbols", "a", @progbits ; \
+ __requiring_symbol__: .byte 0 ; \
+ .size __requiring_symbol__, . - __requiring_symbol__ ; \
+ .previous
+#else
+#define PROVIDE_REQUIRING_SYMBOL() \
+ __asm__ ( ".section \".tbl.requiring_symbols\", " \
+ " \"a\", @progbits\n" \
+ "__requiring_symbol__:\t.byte 0\n" \
+ ".size __requiring_symbol__, " \
+ " . - __requiring_symbol__\n" \
+ ".previous" )
+#endif
/** @} */
@@ -119,11 +166,29 @@
/** Always provide the symbol for the current object (defined by -DOBJECT) */
PROVIDE_SYMBOL ( OBJECT_SYMBOL );
-/** Explicitly require another object */
-#define REQUIRE_OBJECT( _obj ) REQUIRE_SYMBOL ( obj_ ## _obj )
+/**
+ * Request an object
+ *
+ * @v object Object name
+ *
+ * Request an object to be included within the link. If the object
+ * cannot be found, the link will succeed anyway.
+ */
+#define REQUEST_OBJECT( object ) REQUEST_SYMBOL ( obj_ ## object )
-/** Pull in another object if it exists */
-#define REQUEST_OBJECT( _obj ) REQUEST_SYMBOL ( obj_ ## _obj )
+/**
+ * Require an object
+ *
+ * @v object Object name
+ *
+ * Require an object to be included within the link. If the object
+ * cannot be found, the link will fail.
+ *
+ * To use this macro within a file, you must also specify the file's
+ * "requiring symbol" using the REQUIRING_SYMBOL() or
+ * PROVIDE_REQUIRING_SYMBOL() macros.
+ */
+#define REQUIRE_OBJECT( object ) REQUIRE_SYMBOL ( obj_ ## object )
/** @} */
@@ -685,8 +750,8 @@ int __debug_disable;
/** @} */
-/* This file itself is under GPLv2-or-later */
-FILE_LICENCE ( GPL2_OR_LATER );
+/* This file itself is under GPLv2+/UBDL */
+FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
#include <bits/compiler.h>