LLD 13 and GNU ld 2.37 support -z start-stop-gc which allows garbage
collection of C identifier name sections despite the __start_/__stop_
references. GNU ld before 2015-10 had the behavior as well. Simply set
the retain attribute so that GCC 11 (if configure-time binutils is 2.36
or newer)/Clang 13 will set the SHF_GNU_RETAIN section attribute to
prevent garbage collection.
Without the patch, there are linker errors with -z start-stop-gc (LLD default):
```
ld.lld: error: undefined symbol: __start___ell_debug
>> referenced by log.c
>> log.o:(register_debug_section) in archive
ell/.libs/libell-private.a
```
---
ell/log.h | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/ell/log.h b/ell/log.h
index 924523b..32d6b8a 100644
--- a/ell/log.h
+++ b/ell/log.h
@@ -61,12 +61,18 @@ struct l_debug_desc {
unsigned int flags;
} __attribute__((aligned(8)));
+// Set the retain attribute so that the section cannot be discarded by ld
+// --gc-sections -z start-stop-gc. Older compilers would warn for the unknown
+// attribute, so just disable -Wattributes.
#define L_DEBUG_SYMBOL(symbol, format, ...) do { \
+_Pragma("GCC diagnostic push") \
+_Pragma("GCC diagnostic ignored \"-Wattributes\"") \
static struct l_debug_desc symbol \
- __attribute__((used, section("__ell_debug"), aligned(8))) = { \
+ __attribute__((used, retain, section("__ell_debug"), aligned(8))) = { \
.file = __FILE__, .func = __func__, \
.flags = L_DEBUG_FLAG_DEFAULT, \
}; \
+_Pragma("GCC diagnostic pop") \
if (symbol.flags & L_DEBUG_FLAG_PRINT) \
l_log(L_LOG_DEBUG, "%s:%s() " format, __FILE__, \
__func__ , ##__VA_ARGS__); \
--
2.34