Skip to content

Commit

Permalink
Explicit linking behavior
Browse files Browse the repository at this point in the history
Previously mdio relied on GNU `ld`'s well known secret formula
finding the begining 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 optomized away since they are not directly
referenced from `main` (might be unnecessary).
  • Loading branch information
MattCatz committed Oct 29, 2024
1 parent 61bf45c commit ec9f414
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 5 deletions.
3 changes: 2 additions & 1 deletion src/mdio/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -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)
9 changes: 9 additions & 0 deletions src/mdio/cmds.ld
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
SECTIONS
{
.cmds : {
PROVIDE(cmds_start = .);
*(.cmd_registry)
PROVIDE(cmds_end = .);
}
}
INSERT AFTER .data;
2 changes: 1 addition & 1 deletion src/mdio/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
7 changes: 4 additions & 3 deletions src/mdio/mdio.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down

0 comments on commit ec9f414

Please sign in to comment.