Skip to content

Commit 626596e

Browse files
committed
modpost: use a table rather than a giant if/else statement.
We look for symbols of form __mod_<busname>_device_table, and for all but three cases we use a standard interation function (do_table) to walk over the contents and dump out the aliases. Alessandro Rubini did this first, I just repainted the bikeshed a bit. Signed-off-by: Rusty Russell <[email protected]> Cc: Alessandro Rubini <[email protected]>
1 parent cca3e70 commit 626596e

File tree

1 file changed

+73
-119
lines changed

1 file changed

+73
-119
lines changed

scripts/mod/file2alias.c

Lines changed: 73 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ typedef Elf64_Addr kernel_ulong_t;
2828
#endif
2929

3030
#include <ctype.h>
31+
#include <stdbool.h>
3132

3233
typedef uint32_t __u32;
3334
typedef uint16_t __u16;
@@ -948,15 +949,13 @@ static int do_amba_entry(const char *filename,
948949
return 1;
949950
}
950951

951-
/* Ignore any prefix, eg. some architectures prepend _ */
952-
static inline int sym_is(const char *symbol, const char *name)
952+
/* Does namelen bytes of name exactly match the symbol? */
953+
static bool sym_is(const char *name, unsigned namelen, const char *symbol)
953954
{
954-
const char *match;
955+
if (namelen != strlen(symbol))
956+
return false;
955957

956-
match = strstr(symbol, name);
957-
if (!match)
958-
return 0;
959-
return match[strlen(name)] == '\0';
958+
return memcmp(name, symbol, namelen) == 0;
960959
}
961960

962961
static void do_table(void *symval, unsigned long size,
@@ -981,6 +980,43 @@ static void do_table(void *symval, unsigned long size,
981980
}
982981
}
983982

983+
/* This array collects all instances that use the generic do_table above */
984+
struct devtable_switch {
985+
const char *device_id; /* name of table, __mod_<name>_device_table. */
986+
unsigned long id_size;
987+
void *function;
988+
};
989+
990+
static const struct devtable_switch devtable_switch[] = {
991+
{ "acpi", sizeof(struct acpi_device_id), do_acpi_entry },
992+
{ "amba", sizeof(struct amba_id), do_amba_entry },
993+
{ "ap", sizeof(struct ap_device_id), do_ap_entry },
994+
{ "bcma", sizeof(struct bcma_device_id), do_bcma_entry },
995+
{ "ccw", sizeof(struct ccw_device_id), do_ccw_entry },
996+
{ "css", sizeof(struct css_device_id), do_css_entry },
997+
{ "dmi", sizeof(struct dmi_system_id), do_dmi_entry },
998+
{ "eisa", sizeof(struct eisa_device_id), do_eisa_entry },
999+
{ "hid", sizeof(struct hid_device_id), do_hid_entry },
1000+
{ "i2c", sizeof(struct i2c_device_id), do_i2c_entry },
1001+
{ "ieee1394", sizeof(struct ieee1394_device_id), do_ieee1394_entry },
1002+
{ "input", sizeof(struct input_device_id), do_input_entry },
1003+
{ "isa", sizeof(struct isapnp_device_id), do_isapnp_entry },
1004+
{ "mdio", sizeof(struct mdio_device_id), do_mdio_entry },
1005+
{ "of", sizeof(struct of_device_id), do_of_entry },
1006+
{ "parisc", sizeof(struct parisc_device_id), do_parisc_entry },
1007+
{ "pci", sizeof(struct pci_device_id), do_pci_entry },
1008+
{ "pcmcia", sizeof(struct pcmcia_device_id), do_pcmcia_entry },
1009+
{ "platform", sizeof(struct platform_device_id), do_platform_entry },
1010+
{ "sdio", sizeof(struct sdio_device_id), do_sdio_entry },
1011+
{ "serio", sizeof(struct serio_device_id), do_serio_entry },
1012+
{ "spi", sizeof(struct spi_device_id), do_spi_entry },
1013+
{ "ssb", sizeof(struct ssb_device_id), do_ssb_entry },
1014+
{ "vio", sizeof(struct vio_device_id), do_vio_entry },
1015+
{ "virtio", sizeof(struct virtio_device_id), do_virtio_entry },
1016+
{ "vmbus", sizeof(struct hv_vmbus_device_id), do_vmbus_entry },
1017+
{ "zorro", sizeof(struct zorro_device_id), do_zorro_entry },
1018+
};
1019+
9841020
/* Create MODULE_ALIAS() statements.
9851021
* At this time, we cannot write the actual output C source yet,
9861022
* so we write into the mod->dev_table_buf buffer. */
@@ -989,11 +1025,25 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
9891025
{
9901026
void *symval;
9911027
char *zeros = NULL;
1028+
const char *name;
1029+
unsigned int namelen;
9921030

9931031
/* We're looking for a section relative symbol */
9941032
if (!sym->st_shndx || get_secindex(info, sym) >= info->num_sections)
9951033
return;
9961034

1035+
/* All our symbols are of form <prefix>__mod_XXX_device_table. */
1036+
name = strstr(symname, "__mod_");
1037+
if (!name)
1038+
return;
1039+
name += strlen("__mod_");
1040+
namelen = strlen(name);
1041+
if (namelen < strlen("_device_table"))
1042+
return;
1043+
if (strcmp(name + namelen - strlen("_device_table"), "_device_table"))
1044+
return;
1045+
namelen -= strlen("_device_table");
1046+
9971047
/* Handle all-NULL symbols allocated into .bss */
9981048
if (info->sechdrs[get_secindex(info, sym)].sh_type & SHT_NOBITS) {
9991049
zeros = calloc(1, sym->st_size);
@@ -1004,121 +1054,25 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
10041054
+ sym->st_value;
10051055
}
10061056

1007-
if (sym_is(symname, "__mod_pci_device_table"))
1008-
do_table(symval, sym->st_size,
1009-
sizeof(struct pci_device_id), "pci",
1010-
do_pci_entry, mod);
1011-
else if (sym_is(symname, "__mod_usb_device_table"))
1012-
/* special case to handle bcdDevice ranges */
1057+
/* First handle the "special" cases */
1058+
if (sym_is(name, namelen, "usb"))
10131059
do_usb_table(symval, sym->st_size, mod);
1014-
else if (sym_is(symname, "__mod_hid_device_table"))
1015-
do_table(symval, sym->st_size,
1016-
sizeof(struct hid_device_id), "hid",
1017-
do_hid_entry, mod);
1018-
else if (sym_is(symname, "__mod_ieee1394_device_table"))
1019-
do_table(symval, sym->st_size,
1020-
sizeof(struct ieee1394_device_id), "ieee1394",
1021-
do_ieee1394_entry, mod);
1022-
else if (sym_is(symname, "__mod_ccw_device_table"))
1023-
do_table(symval, sym->st_size,
1024-
sizeof(struct ccw_device_id), "ccw",
1025-
do_ccw_entry, mod);
1026-
else if (sym_is(symname, "__mod_ap_device_table"))
1027-
do_table(symval, sym->st_size,
1028-
sizeof(struct ap_device_id), "ap",
1029-
do_ap_entry, mod);
1030-
else if (sym_is(symname, "__mod_css_device_table"))
1031-
do_table(symval, sym->st_size,
1032-
sizeof(struct css_device_id), "css",
1033-
do_css_entry, mod);
1034-
else if (sym_is(symname, "__mod_serio_device_table"))
1035-
do_table(symval, sym->st_size,
1036-
sizeof(struct serio_device_id), "serio",
1037-
do_serio_entry, mod);
1038-
else if (sym_is(symname, "__mod_acpi_device_table"))
1039-
do_table(symval, sym->st_size,
1040-
sizeof(struct acpi_device_id), "acpi",
1041-
do_acpi_entry, mod);
1042-
else if (sym_is(symname, "__mod_pnp_device_table"))
1060+
else if (sym_is(name, namelen, "pnp"))
10431061
do_pnp_device_entry(symval, sym->st_size, mod);
1044-
else if (sym_is(symname, "__mod_pnp_card_device_table"))
1062+
else if (sym_is(name, namelen, "pnp_card"))
10451063
do_pnp_card_entries(symval, sym->st_size, mod);
1046-
else if (sym_is(symname, "__mod_pcmcia_device_table"))
1047-
do_table(symval, sym->st_size,
1048-
sizeof(struct pcmcia_device_id), "pcmcia",
1049-
do_pcmcia_entry, mod);
1050-
else if (sym_is(symname, "__mod_of_device_table"))
1051-
do_table(symval, sym->st_size,
1052-
sizeof(struct of_device_id), "of",
1053-
do_of_entry, mod);
1054-
else if (sym_is(symname, "__mod_vio_device_table"))
1055-
do_table(symval, sym->st_size,
1056-
sizeof(struct vio_device_id), "vio",
1057-
do_vio_entry, mod);
1058-
else if (sym_is(symname, "__mod_input_device_table"))
1059-
do_table(symval, sym->st_size,
1060-
sizeof(struct input_device_id), "input",
1061-
do_input_entry, mod);
1062-
else if (sym_is(symname, "__mod_eisa_device_table"))
1063-
do_table(symval, sym->st_size,
1064-
sizeof(struct eisa_device_id), "eisa",
1065-
do_eisa_entry, mod);
1066-
else if (sym_is(symname, "__mod_parisc_device_table"))
1067-
do_table(symval, sym->st_size,
1068-
sizeof(struct parisc_device_id), "parisc",
1069-
do_parisc_entry, mod);
1070-
else if (sym_is(symname, "__mod_sdio_device_table"))
1071-
do_table(symval, sym->st_size,
1072-
sizeof(struct sdio_device_id), "sdio",
1073-
do_sdio_entry, mod);
1074-
else if (sym_is(symname, "__mod_ssb_device_table"))
1075-
do_table(symval, sym->st_size,
1076-
sizeof(struct ssb_device_id), "ssb",
1077-
do_ssb_entry, mod);
1078-
else if (sym_is(symname, "__mod_bcma_device_table"))
1079-
do_table(symval, sym->st_size,
1080-
sizeof(struct bcma_device_id), "bcma",
1081-
do_bcma_entry, mod);
1082-
else if (sym_is(symname, "__mod_virtio_device_table"))
1083-
do_table(symval, sym->st_size,
1084-
sizeof(struct virtio_device_id), "virtio",
1085-
do_virtio_entry, mod);
1086-
else if (sym_is(symname, "__mod_vmbus_device_table"))
1087-
do_table(symval, sym->st_size,
1088-
sizeof(struct hv_vmbus_device_id), "vmbus",
1089-
do_vmbus_entry, mod);
1090-
else if (sym_is(symname, "__mod_i2c_device_table"))
1091-
do_table(symval, sym->st_size,
1092-
sizeof(struct i2c_device_id), "i2c",
1093-
do_i2c_entry, mod);
1094-
else if (sym_is(symname, "__mod_spi_device_table"))
1095-
do_table(symval, sym->st_size,
1096-
sizeof(struct spi_device_id), "spi",
1097-
do_spi_entry, mod);
1098-
else if (sym_is(symname, "__mod_dmi_device_table"))
1099-
do_table(symval, sym->st_size,
1100-
sizeof(struct dmi_system_id), "dmi",
1101-
do_dmi_entry, mod);
1102-
else if (sym_is(symname, "__mod_platform_device_table"))
1103-
do_table(symval, sym->st_size,
1104-
sizeof(struct platform_device_id), "platform",
1105-
do_platform_entry, mod);
1106-
else if (sym_is(symname, "__mod_mdio_device_table"))
1107-
do_table(symval, sym->st_size,
1108-
sizeof(struct mdio_device_id), "mdio",
1109-
do_mdio_entry, mod);
1110-
else if (sym_is(symname, "__mod_zorro_device_table"))
1111-
do_table(symval, sym->st_size,
1112-
sizeof(struct zorro_device_id), "zorro",
1113-
do_zorro_entry, mod);
1114-
else if (sym_is(symname, "__mod_isapnp_device_table"))
1115-
do_table(symval, sym->st_size,
1116-
sizeof(struct isapnp_device_id), "isa",
1117-
do_isapnp_entry, mod);
1118-
else if (sym_is(symname, "__mod_amba_device_table"))
1119-
do_table(symval, sym->st_size,
1120-
sizeof(struct amba_id), "amba",
1121-
do_amba_entry, mod);
1064+
else {
1065+
const struct devtable_switch *p = devtable_switch;
1066+
unsigned int i;
1067+
1068+
for (i = 0; i < ARRAY_SIZE(devtable_switch); i++, p++) {
1069+
if (sym_is(name, namelen, p->device_id)) {
1070+
do_table(symval, sym->st_size, p->id_size,
1071+
p->device_id, p->function, mod);
1072+
break;
1073+
}
1074+
}
1075+
}
11221076
free(zeros);
11231077
}
11241078

0 commit comments

Comments
 (0)