Skip to content

Commit e49ce14

Browse files
committed
modpost: use linker section to generate table.
This means (most) future busses need only have one hunk in their patch. Also took the opportunity to check that function matches the type. Again, inspired by Alessandro's patch series. Signed-off-by: Rusty Russell <[email protected]> Cc: Alessandro Rubini <[email protected]>
1 parent 626596e commit e49ce14

File tree

1 file changed

+61
-45
lines changed

1 file changed

+61
-45
lines changed

scripts/mod/file2alias.c

Lines changed: 61 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,35 @@ typedef unsigned char __u8;
3939
* we handle those differences explicitly below */
4040
#include "../../include/linux/mod_devicetable.h"
4141

42+
/* This array collects all instances that use the generic do_table */
43+
struct devtable {
44+
const char *device_id; /* name of table, __mod_<name>_device_table. */
45+
unsigned long id_size;
46+
void *function;
47+
};
48+
49+
/* We construct a table of pointers in an ELF section (pointers generally
50+
* go unpadded by gcc). ld creates boundary syms for us. */
51+
extern struct devtable *__start___devtable[], *__stop___devtable[];
52+
#define ___cat(a,b) a ## b
53+
#define __cat(a,b) ___cat(a,b)
54+
55+
#if __GNUC__ == 3 && __GNUC_MINOR__ < 3
56+
# define __used __attribute__((__unused__))
57+
#else
58+
# define __used __attribute__((__used__))
59+
#endif
60+
61+
/* Add a table entry. We test function type matches while we're here. */
62+
#define ADD_TO_DEVTABLE(device_id, type, function) \
63+
static struct devtable __cat(devtable,__LINE__) = { \
64+
device_id + 0*sizeof((function)((const char *)NULL, \
65+
(type *)NULL, \
66+
(char *)NULL)), \
67+
sizeof(type), (function) }; \
68+
static struct devtable *__attribute__((section("__devtable"))) \
69+
__used __cat(devtable_ptr,__LINE__) = &__cat(devtable,__LINE__)
70+
4271
#define ADD(str, sep, cond, field) \
4372
do { \
4473
strcat(str, sep); \
@@ -290,6 +319,7 @@ static int do_hid_entry(const char *filename,
290319

291320
return 1;
292321
}
322+
ADD_TO_DEVTABLE("hid", struct hid_device_id, do_hid_entry);
293323

294324
/* Looks like: ieee1394:venNmoNspNverN */
295325
static int do_ieee1394_entry(const char *filename,
@@ -314,6 +344,7 @@ static int do_ieee1394_entry(const char *filename,
314344
add_wildcard(alias);
315345
return 1;
316346
}
347+
ADD_TO_DEVTABLE("ieee1394", struct ieee1394_device_id, do_ieee1394_entry);
317348

318349
/* Looks like: pci:vNdNsvNsdNbcNscNiN. */
319350
static int do_pci_entry(const char *filename,
@@ -357,6 +388,7 @@ static int do_pci_entry(const char *filename,
357388
add_wildcard(alias);
358389
return 1;
359390
}
391+
ADD_TO_DEVTABLE("pci", struct pci_device_id, do_pci_entry);
360392

361393
/* looks like: "ccw:tNmNdtNdmN" */
362394
static int do_ccw_entry(const char *filename,
@@ -380,6 +412,7 @@ static int do_ccw_entry(const char *filename,
380412
add_wildcard(alias);
381413
return 1;
382414
}
415+
ADD_TO_DEVTABLE("ccw", struct ccw_device_id, do_ccw_entry);
383416

384417
/* looks like: "ap:tN" */
385418
static int do_ap_entry(const char *filename,
@@ -388,6 +421,7 @@ static int do_ap_entry(const char *filename,
388421
sprintf(alias, "ap:t%02X*", id->dev_type);
389422
return 1;
390423
}
424+
ADD_TO_DEVTABLE("ap", struct ap_device_id, do_ap_entry);
391425

392426
/* looks like: "css:tN" */
393427
static int do_css_entry(const char *filename,
@@ -396,6 +430,7 @@ static int do_css_entry(const char *filename,
396430
sprintf(alias, "css:t%01X", id->type);
397431
return 1;
398432
}
433+
ADD_TO_DEVTABLE("css", struct css_device_id, do_css_entry);
399434

400435
/* Looks like: "serio:tyNprNidNexN" */
401436
static int do_serio_entry(const char *filename,
@@ -415,6 +450,7 @@ static int do_serio_entry(const char *filename,
415450
add_wildcard(alias);
416451
return 1;
417452
}
453+
ADD_TO_DEVTABLE("serio", struct serio_device_id, do_serio_entry);
418454

419455
/* looks like: "acpi:ACPI0003 or acpi:PNP0C0B" or "acpi:LNXVIDEO" */
420456
static int do_acpi_entry(const char *filename,
@@ -423,6 +459,7 @@ static int do_acpi_entry(const char *filename,
423459
sprintf(alias, "acpi*:%s:*", id->id);
424460
return 1;
425461
}
462+
ADD_TO_DEVTABLE("acpi", struct acpi_device_id, do_acpi_entry);
426463

427464
/* looks like: "pnp:dD" */
428465
static void do_pnp_device_entry(void *symval, unsigned long size,
@@ -545,8 +582,7 @@ static int do_pcmcia_entry(const char *filename,
545582
add_wildcard(alias);
546583
return 1;
547584
}
548-
549-
585+
ADD_TO_DEVTABLE("pcmcia", struct pcmcia_device_id, do_pcmcia_entry);
550586

551587
static int do_of_entry (const char *filename, struct of_device_id *of, char *alias)
552588
{
@@ -569,6 +605,7 @@ static int do_of_entry (const char *filename, struct of_device_id *of, char *ali
569605
add_wildcard(alias);
570606
return 1;
571607
}
608+
ADD_TO_DEVTABLE("of", struct of_device_id, do_of_entry);
572609

573610
static int do_vio_entry(const char *filename, struct vio_device_id *vio,
574611
char *alias)
@@ -586,6 +623,7 @@ static int do_vio_entry(const char *filename, struct vio_device_id *vio,
586623
add_wildcard(alias);
587624
return 1;
588625
}
626+
ADD_TO_DEVTABLE("vio", struct vio_device_id, do_vio_entry);
589627

590628
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
591629

@@ -641,6 +679,7 @@ static int do_input_entry(const char *filename, struct input_device_id *id,
641679
do_input(alias, id->swbit, 0, INPUT_DEVICE_ID_SW_MAX);
642680
return 1;
643681
}
682+
ADD_TO_DEVTABLE("input", struct input_device_id, do_input_entry);
644683

645684
static int do_eisa_entry(const char *filename, struct eisa_device_id *eisa,
646685
char *alias)
@@ -651,6 +690,7 @@ static int do_eisa_entry(const char *filename, struct eisa_device_id *eisa,
651690
strcat(alias, "*");
652691
return 1;
653692
}
693+
ADD_TO_DEVTABLE("eisa", struct eisa_device_id, do_eisa_entry);
654694

655695
/* Looks like: parisc:tNhvNrevNsvN */
656696
static int do_parisc_entry(const char *filename, struct parisc_device_id *id,
@@ -670,6 +710,7 @@ static int do_parisc_entry(const char *filename, struct parisc_device_id *id,
670710
add_wildcard(alias);
671711
return 1;
672712
}
713+
ADD_TO_DEVTABLE("parisc", struct parisc_device_id, do_parisc_entry);
673714

674715
/* Looks like: sdio:cNvNdN. */
675716
static int do_sdio_entry(const char *filename,
@@ -686,6 +727,7 @@ static int do_sdio_entry(const char *filename,
686727
add_wildcard(alias);
687728
return 1;
688729
}
730+
ADD_TO_DEVTABLE("sdio", struct sdio_device_id, do_sdio_entry);
689731

690732
/* Looks like: ssb:vNidNrevN. */
691733
static int do_ssb_entry(const char *filename,
@@ -702,6 +744,7 @@ static int do_ssb_entry(const char *filename,
702744
add_wildcard(alias);
703745
return 1;
704746
}
747+
ADD_TO_DEVTABLE("ssb", struct ssb_device_id, do_ssb_entry);
705748

706749
/* Looks like: bcma:mNidNrevNclN. */
707750
static int do_bcma_entry(const char *filename,
@@ -720,6 +763,7 @@ static int do_bcma_entry(const char *filename,
720763
add_wildcard(alias);
721764
return 1;
722765
}
766+
ADD_TO_DEVTABLE("bcma", struct bcma_device_id, do_bcma_entry);
723767

724768
/* Looks like: virtio:dNvN */
725769
static int do_virtio_entry(const char *filename, struct virtio_device_id *id,
@@ -735,6 +779,7 @@ static int do_virtio_entry(const char *filename, struct virtio_device_id *id,
735779
add_wildcard(alias);
736780
return 1;
737781
}
782+
ADD_TO_DEVTABLE("virtio", struct virtio_device_id, do_virtio_entry);
738783

739784
/*
740785
* Looks like: vmbus:guid
@@ -756,6 +801,7 @@ static int do_vmbus_entry(const char *filename, struct hv_vmbus_device_id *id,
756801

757802
return 1;
758803
}
804+
ADD_TO_DEVTABLE("vmbus", struct hv_vmbus_device_id, do_vmbus_entry);
759805

760806
/* Looks like: i2c:S */
761807
static int do_i2c_entry(const char *filename, struct i2c_device_id *id,
@@ -765,6 +811,7 @@ static int do_i2c_entry(const char *filename, struct i2c_device_id *id,
765811

766812
return 1;
767813
}
814+
ADD_TO_DEVTABLE("i2c", struct i2c_device_id, do_i2c_entry);
768815

769816
/* Looks like: spi:S */
770817
static int do_spi_entry(const char *filename, struct spi_device_id *id,
@@ -774,6 +821,7 @@ static int do_spi_entry(const char *filename, struct spi_device_id *id,
774821

775822
return 1;
776823
}
824+
ADD_TO_DEVTABLE("spi", struct spi_device_id, do_spi_entry);
777825

778826
static const struct dmifield {
779827
const char *prefix;
@@ -828,13 +876,15 @@ static int do_dmi_entry(const char *filename, struct dmi_system_id *id,
828876
strcat(alias, ":");
829877
return 1;
830878
}
879+
ADD_TO_DEVTABLE("dmi", struct dmi_system_id, do_dmi_entry);
831880

832881
static int do_platform_entry(const char *filename,
833882
struct platform_device_id *id, char *alias)
834883
{
835884
sprintf(alias, PLATFORM_MODULE_PREFIX "%s", id->name);
836885
return 1;
837886
}
887+
ADD_TO_DEVTABLE("platform", struct platform_device_id, do_platform_entry);
838888

839889
static int do_mdio_entry(const char *filename,
840890
struct mdio_device_id *id, char *alias)
@@ -857,6 +907,7 @@ static int do_mdio_entry(const char *filename,
857907

858908
return 1;
859909
}
910+
ADD_TO_DEVTABLE("mdio", struct mdio_device_id, do_mdio_entry);
860911

861912
/* Looks like: zorro:iN. */
862913
static int do_zorro_entry(const char *filename, struct zorro_device_id *id,
@@ -867,6 +918,7 @@ static int do_zorro_entry(const char *filename, struct zorro_device_id *id,
867918
ADD(alias, "i", id->id != ZORRO_WILDCARD, id->id);
868919
return 1;
869920
}
921+
ADD_TO_DEVTABLE("zorro", struct zorro_device_id, do_zorro_entry);
870922

871923
/* looks like: "pnp:dD" */
872924
static int do_isapnp_entry(const char *filename,
@@ -880,6 +932,7 @@ static int do_isapnp_entry(const char *filename,
880932
(id->function >> 12) & 0x0f, (id->function >> 8) & 0x0f);
881933
return 1;
882934
}
935+
ADD_TO_DEVTABLE("isa", struct isapnp_device_id, do_isapnp_entry);
883936

884937
/*
885938
* Append a match expression for a single masked hex digit.
@@ -948,6 +1001,7 @@ static int do_amba_entry(const char *filename,
9481001

9491002
return 1;
9501003
}
1004+
ADD_TO_DEVTABLE("amba", struct amba_id, do_amba_entry);
9511005

9521006
/* Does namelen bytes of name exactly match the symbol? */
9531007
static bool sym_is(const char *name, unsigned namelen, const char *symbol)
@@ -980,43 +1034,6 @@ static void do_table(void *symval, unsigned long size,
9801034
}
9811035
}
9821036

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-
10201037
/* Create MODULE_ALIAS() statements.
10211038
* At this time, we cannot write the actual output C source yet,
10221039
* so we write into the mod->dev_table_buf buffer. */
@@ -1062,13 +1079,12 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
10621079
else if (sym_is(name, namelen, "pnp_card"))
10631080
do_pnp_card_entries(symval, sym->st_size, mod);
10641081
else {
1065-
const struct devtable_switch *p = devtable_switch;
1066-
unsigned int i;
1082+
struct devtable **p;
10671083

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);
1084+
for (p = __start___devtable; p < __stop___devtable; p++) {
1085+
if (sym_is(name, namelen, (*p)->device_id)) {
1086+
do_table(symval, sym->st_size, (*p)->id_size,
1087+
(*p)->device_id, (*p)->function, mod);
10721088
break;
10731089
}
10741090
}

0 commit comments

Comments
 (0)