From 71056eeedd77cb92054230062b67c8d3f49da237 Mon Sep 17 00:00:00 2001 From: Matthew Cather Date: Tue, 29 Oct 2024 16:07:32 -0500 Subject: [PATCH 1/2] Explicit linking behavior Previously mdio relied on GNU `ld`'s well known secret formula finding the beginning and end of sections. Compiling with LTO and optimizations seems to break that. Now there is a linker script that explains to the linker what is happening. `externally_visible` was also added to make sure the cmd functions do not get optimized away since they are not directly referenced from `main` (might be unnecessary). --- src/mdio/Makefile.am | 3 ++- src/mdio/cmds.ld | 9 +++++++++ src/mdio/main.c | 2 +- src/mdio/mdio.h | 7 ++++--- 4 files changed, 16 insertions(+), 5 deletions(-) create mode 100644 src/mdio/cmds.ld diff --git a/src/mdio/Makefile.am b/src/mdio/Makefile.am index b7b6935..5854a45 100644 --- a/src/mdio/Makefile.am +++ b/src/mdio/Makefile.am @@ -2,4 +2,5 @@ sbin_PROGRAMS = mdio mdio_SOURCES = bus.c main.c mdio.c mdio.h mva.c mvls.c phy.c print_phy.c xrs.c mdio_CFLAGS = -Wall -Wextra -Werror -Wno-unused-parameter -I $(top_srcdir)/include $(mnl_CFLAGS) -mdio_LDADD = $(mnl_LIBS) +mdio_LDFLAGS = -T cmds.ld +mdio_LDADD = $(mnl_LIBS) \ No newline at end of file diff --git a/src/mdio/cmds.ld b/src/mdio/cmds.ld new file mode 100644 index 0000000..12a7dfe --- /dev/null +++ b/src/mdio/cmds.ld @@ -0,0 +1,9 @@ +SECTIONS +{ + .cmds : { + PROVIDE(cmds_start = .); + *(.cmd_registry) + PROVIDE(cmds_end = .); + } +} +INSERT AFTER .data; diff --git a/src/mdio/main.c b/src/mdio/main.c index d72f885..0ddd381 100644 --- a/src/mdio/main.c +++ b/src/mdio/main.c @@ -167,7 +167,7 @@ int main(int argc, char **argv) if (!arg) return bus_status(bus) ? 1 : 0; - for (cmd = &__start_cmds; cmd < &__stop_cmds; cmd++) { + for (cmd = &cmds_start; cmd < &cmds_end; cmd++) { if (!strcmp(cmd->name, arg)) { argv_pop(&argc, &argv); return cmd->exec(bus, argc, argv) ? 1 : 0; diff --git a/src/mdio/mdio.h b/src/mdio/mdio.h index 6fa0412..b158f0f 100644 --- a/src/mdio/mdio.h +++ b/src/mdio/mdio.h @@ -55,12 +55,13 @@ struct cmd { int (*exec)(const char *bus, int argc, char **argv); }; +// Derived from https://stackoverflow.com/a/4152185 #define DEFINE_CMD(_name, _exec) \ - __attribute__(( section("cmds"), aligned(__alignof__(struct cmd)) )) \ + __attribute__((externally_visible, section(".cmd_registry"), aligned(__alignof__(struct cmd)) )) \ struct cmd _exec ## _cmd = { .name = _name, .exec = _exec } -extern struct cmd __start_cmds; -extern struct cmd __stop_cmds; +extern struct cmd cmds_start; +extern struct cmd cmds_end; void print_phy_bmcr (uint16_t val); void print_phy_bmsr (uint16_t val); From 6d15571c7b25490355c895b526eec3e0f105f9fb Mon Sep 17 00:00:00 2001 From: Matthew Cather Date: Wed, 30 Oct 2024 17:10:59 -0500 Subject: [PATCH 2/2] Use more portable attribute --- src/mdio/mdio.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/mdio/mdio.h b/src/mdio/mdio.h index b158f0f..684be7f 100644 --- a/src/mdio/mdio.h +++ b/src/mdio/mdio.h @@ -57,7 +57,7 @@ struct cmd { // Derived from https://stackoverflow.com/a/4152185 #define DEFINE_CMD(_name, _exec) \ - __attribute__((externally_visible, section(".cmd_registry"), aligned(__alignof__(struct cmd)) )) \ + __attribute__((used, section(".cmd_registry"), aligned(__alignof__(struct cmd)) )) \ struct cmd _exec ## _cmd = { .name = _name, .exec = _exec } extern struct cmd cmds_start;