diff options
Diffstat (limited to 'scripts/mod')
| -rw-r--r-- | scripts/mod/devicetable-offsets.c | 3 | ||||
| -rw-r--r-- | scripts/mod/file2alias.c | 34 | ||||
| -rw-r--r-- | scripts/mod/modpost.c | 25 | ||||
| -rw-r--r-- | scripts/mod/modpost.h | 2 |
4 files changed, 51 insertions, 13 deletions
diff --git a/scripts/mod/devicetable-offsets.c b/scripts/mod/devicetable-offsets.c index bb5d115ca671..f282516acc7b 100644 --- a/scripts/mod/devicetable-offsets.c +++ b/scripts/mod/devicetable-offsets.c | |||
| @@ -174,6 +174,9 @@ int main(void) | |||
| 174 | DEVID_FIELD(x86_cpu_id, model); | 174 | DEVID_FIELD(x86_cpu_id, model); |
| 175 | DEVID_FIELD(x86_cpu_id, vendor); | 175 | DEVID_FIELD(x86_cpu_id, vendor); |
| 176 | 176 | ||
| 177 | DEVID(cpu_feature); | ||
| 178 | DEVID_FIELD(cpu_feature, feature); | ||
| 179 | |||
| 177 | DEVID(mei_cl_device_id); | 180 | DEVID(mei_cl_device_id); |
| 178 | DEVID_FIELD(mei_cl_device_id, name); | 181 | DEVID_FIELD(mei_cl_device_id, name); |
| 179 | 182 | ||
diff --git a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c index 25e5cb0aaef6..1924990a737f 100644 --- a/scripts/mod/file2alias.c +++ b/scripts/mod/file2alias.c | |||
| @@ -42,7 +42,7 @@ typedef unsigned char __u8; | |||
| 42 | 42 | ||
| 43 | /* This array collects all instances that use the generic do_table */ | 43 | /* This array collects all instances that use the generic do_table */ |
| 44 | struct devtable { | 44 | struct devtable { |
| 45 | const char *device_id; /* name of table, __mod_<name>_device_table. */ | 45 | const char *device_id; /* name of table, __mod_<name>__*_device_table. */ |
| 46 | unsigned long id_size; | 46 | unsigned long id_size; |
| 47 | void *function; | 47 | void *function; |
| 48 | }; | 48 | }; |
| @@ -146,7 +146,8 @@ static void device_id_check(const char *modname, const char *device_id, | |||
| 146 | 146 | ||
| 147 | if (size % id_size || size < id_size) { | 147 | if (size % id_size || size < id_size) { |
| 148 | fatal("%s: sizeof(struct %s_device_id)=%lu is not a modulo " | 148 | fatal("%s: sizeof(struct %s_device_id)=%lu is not a modulo " |
| 149 | "of the size of section __mod_%s_device_table=%lu.\n" | 149 | "of the size of " |
| 150 | "section __mod_%s__<identifier>_device_table=%lu.\n" | ||
| 150 | "Fix definition of struct %s_device_id " | 151 | "Fix definition of struct %s_device_id " |
| 151 | "in mod_devicetable.h\n", | 152 | "in mod_devicetable.h\n", |
| 152 | modname, device_id, id_size, device_id, size, device_id); | 153 | modname, device_id, id_size, device_id, size, device_id); |
| @@ -1110,7 +1111,7 @@ static int do_amba_entry(const char *filename, | |||
| 1110 | } | 1111 | } |
| 1111 | ADD_TO_DEVTABLE("amba", amba_id, do_amba_entry); | 1112 | ADD_TO_DEVTABLE("amba", amba_id, do_amba_entry); |
| 1112 | 1113 | ||
| 1113 | /* LOOKS like x86cpu:vendor:VVVV:family:FFFF:model:MMMM:feature:*,FEAT,* | 1114 | /* LOOKS like cpu:type:x86,venVVVVfamFFFFmodMMMM:feature:*,FEAT,* |
| 1114 | * All fields are numbers. It would be nicer to use strings for vendor | 1115 | * All fields are numbers. It would be nicer to use strings for vendor |
| 1115 | * and feature, but getting those out of the build system here is too | 1116 | * and feature, but getting those out of the build system here is too |
| 1116 | * complicated. | 1117 | * complicated. |
| @@ -1124,10 +1125,10 @@ static int do_x86cpu_entry(const char *filename, void *symval, | |||
| 1124 | DEF_FIELD(symval, x86_cpu_id, model); | 1125 | DEF_FIELD(symval, x86_cpu_id, model); |
| 1125 | DEF_FIELD(symval, x86_cpu_id, vendor); | 1126 | DEF_FIELD(symval, x86_cpu_id, vendor); |
| 1126 | 1127 | ||
| 1127 | strcpy(alias, "x86cpu:"); | 1128 | strcpy(alias, "cpu:type:x86,"); |
| 1128 | ADD(alias, "vendor:", vendor != X86_VENDOR_ANY, vendor); | 1129 | ADD(alias, "ven", vendor != X86_VENDOR_ANY, vendor); |
| 1129 | ADD(alias, ":family:", family != X86_FAMILY_ANY, family); | 1130 | ADD(alias, "fam", family != X86_FAMILY_ANY, family); |
| 1130 | ADD(alias, ":model:", model != X86_MODEL_ANY, model); | 1131 | ADD(alias, "mod", model != X86_MODEL_ANY, model); |
| 1131 | strcat(alias, ":feature:*"); | 1132 | strcat(alias, ":feature:*"); |
| 1132 | if (feature != X86_FEATURE_ANY) | 1133 | if (feature != X86_FEATURE_ANY) |
| 1133 | sprintf(alias + strlen(alias), "%04X*", feature); | 1134 | sprintf(alias + strlen(alias), "%04X*", feature); |
| @@ -1135,6 +1136,16 @@ static int do_x86cpu_entry(const char *filename, void *symval, | |||
| 1135 | } | 1136 | } |
| 1136 | ADD_TO_DEVTABLE("x86cpu", x86_cpu_id, do_x86cpu_entry); | 1137 | ADD_TO_DEVTABLE("x86cpu", x86_cpu_id, do_x86cpu_entry); |
| 1137 | 1138 | ||
| 1139 | /* LOOKS like cpu:type:*:feature:*FEAT* */ | ||
| 1140 | static int do_cpu_entry(const char *filename, void *symval, char *alias) | ||
| 1141 | { | ||
| 1142 | DEF_FIELD(symval, cpu_feature, feature); | ||
| 1143 | |||
| 1144 | sprintf(alias, "cpu:type:*:feature:*%04X*", feature); | ||
| 1145 | return 1; | ||
| 1146 | } | ||
| 1147 | ADD_TO_DEVTABLE("cpu", cpu_feature, do_cpu_entry); | ||
| 1148 | |||
| 1138 | /* Looks like: mei:S */ | 1149 | /* Looks like: mei:S */ |
| 1139 | static int do_mei_entry(const char *filename, void *symval, | 1150 | static int do_mei_entry(const char *filename, void *symval, |
| 1140 | char *alias) | 1151 | char *alias) |
| @@ -1206,7 +1217,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, | |||
| 1206 | { | 1217 | { |
| 1207 | void *symval; | 1218 | void *symval; |
| 1208 | char *zeros = NULL; | 1219 | char *zeros = NULL; |
| 1209 | const char *name; | 1220 | const char *name, *identifier; |
| 1210 | unsigned int namelen; | 1221 | unsigned int namelen; |
| 1211 | 1222 | ||
| 1212 | /* We're looking for a section relative symbol */ | 1223 | /* We're looking for a section relative symbol */ |
| @@ -1217,7 +1228,7 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, | |||
| 1217 | if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT) | 1228 | if (ELF_ST_TYPE(sym->st_info) != STT_OBJECT) |
| 1218 | return; | 1229 | return; |
| 1219 | 1230 | ||
| 1220 | /* All our symbols are of form <prefix>__mod_XXX_device_table. */ | 1231 | /* All our symbols are of form <prefix>__mod_<name>__<identifier>_device_table. */ |
| 1221 | name = strstr(symname, "__mod_"); | 1232 | name = strstr(symname, "__mod_"); |
| 1222 | if (!name) | 1233 | if (!name) |
| 1223 | return; | 1234 | return; |
| @@ -1227,7 +1238,10 @@ void handle_moddevtable(struct module *mod, struct elf_info *info, | |||
| 1227 | return; | 1238 | return; |
| 1228 | if (strcmp(name + namelen - strlen("_device_table"), "_device_table")) | 1239 | if (strcmp(name + namelen - strlen("_device_table"), "_device_table")) |
| 1229 | return; | 1240 | return; |
| 1230 | namelen -= strlen("_device_table"); | 1241 | identifier = strstr(name, "__"); |
| 1242 | if (!identifier) | ||
| 1243 | return; | ||
| 1244 | namelen = identifier - name; | ||
| 1231 | 1245 | ||
| 1232 | /* Handle all-NULL symbols allocated into .bss */ | 1246 | /* Handle all-NULL symbols allocated into .bss */ |
| 1233 | if (info->sechdrs[get_secindex(info, sym)].sh_type & SHT_NOBITS) { | 1247 | if (info->sechdrs[get_secindex(info, sym)].sh_type & SHT_NOBITS) { |
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 99a45fdc1bbf..066355673930 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c | |||
| @@ -623,7 +623,10 @@ static void handle_modversions(struct module *mod, struct elf_info *info, | |||
| 623 | 623 | ||
| 624 | switch (sym->st_shndx) { | 624 | switch (sym->st_shndx) { |
| 625 | case SHN_COMMON: | 625 | case SHN_COMMON: |
| 626 | warn("\"%s\" [%s] is COMMON symbol\n", symname, mod->name); | 626 | if (!strncmp(symname, "__gnu_lto_", sizeof("__gnu_lto_")-1)) { |
| 627 | /* Should warn here, but modpost runs before the linker */ | ||
| 628 | } else | ||
| 629 | warn("\"%s\" [%s] is COMMON symbol\n", symname, mod->name); | ||
| 627 | break; | 630 | break; |
| 628 | case SHN_UNDEF: | 631 | case SHN_UNDEF: |
| 629 | /* undefined symbol */ | 632 | /* undefined symbol */ |
| @@ -849,6 +852,7 @@ static const char *section_white_list[] = | |||
| 849 | ".xt.lit", /* xtensa */ | 852 | ".xt.lit", /* xtensa */ |
| 850 | ".arcextmap*", /* arc */ | 853 | ".arcextmap*", /* arc */ |
| 851 | ".gnu.linkonce.arcext*", /* arc : modules */ | 854 | ".gnu.linkonce.arcext*", /* arc : modules */ |
| 855 | ".gnu.lto*", | ||
| 852 | NULL | 856 | NULL |
| 853 | }; | 857 | }; |
| 854 | 858 | ||
| @@ -1455,6 +1459,10 @@ static void check_section_mismatch(const char *modname, struct elf_info *elf, | |||
| 1455 | to = find_elf_symbol(elf, r->r_addend, sym); | 1459 | to = find_elf_symbol(elf, r->r_addend, sym); |
| 1456 | tosym = sym_name(elf, to); | 1460 | tosym = sym_name(elf, to); |
| 1457 | 1461 | ||
| 1462 | if (!strncmp(fromsym, "reference___initcall", | ||
| 1463 | sizeof("reference___initcall")-1)) | ||
| 1464 | return; | ||
| 1465 | |||
| 1458 | /* check whitelist - we may ignore it */ | 1466 | /* check whitelist - we may ignore it */ |
| 1459 | if (secref_whitelist(mismatch, | 1467 | if (secref_whitelist(mismatch, |
| 1460 | fromsec, fromsym, tosec, tosym)) { | 1468 | fromsec, fromsym, tosec, tosym)) { |
| @@ -1693,6 +1701,19 @@ static void check_sec_ref(struct module *mod, const char *modname, | |||
| 1693 | } | 1701 | } |
| 1694 | } | 1702 | } |
| 1695 | 1703 | ||
| 1704 | static char *remove_dot(char *s) | ||
| 1705 | { | ||
| 1706 | char *end; | ||
| 1707 | int n = strcspn(s, "."); | ||
| 1708 | |||
| 1709 | if (n > 0 && s[n] != 0) { | ||
| 1710 | strtoul(s + n + 1, &end, 10); | ||
| 1711 | if (end > s + n + 1 && (*end == '.' || *end == 0)) | ||
| 1712 | s[n] = 0; | ||
| 1713 | } | ||
| 1714 | return s; | ||
| 1715 | } | ||
| 1716 | |||
| 1696 | static void read_symbols(char *modname) | 1717 | static void read_symbols(char *modname) |
| 1697 | { | 1718 | { |
| 1698 | const char *symname; | 1719 | const char *symname; |
| @@ -1731,7 +1752,7 @@ static void read_symbols(char *modname) | |||
| 1731 | } | 1752 | } |
| 1732 | 1753 | ||
| 1733 | for (sym = info.symtab_start; sym < info.symtab_stop; sym++) { | 1754 | for (sym = info.symtab_start; sym < info.symtab_stop; sym++) { |
| 1734 | symname = info.strtab + sym->st_name; | 1755 | symname = remove_dot(info.strtab + sym->st_name); |
| 1735 | 1756 | ||
| 1736 | handle_modversions(mod, &info, sym, symname); | 1757 | handle_modversions(mod, &info, sym, symname); |
| 1737 | handle_moddevtable(mod, &info, sym, symname); | 1758 | handle_moddevtable(mod, &info, sym, symname); |
diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h index 51207e4d5f8b..168b43dc0a59 100644 --- a/scripts/mod/modpost.h +++ b/scripts/mod/modpost.h | |||
| @@ -127,7 +127,7 @@ struct elf_info { | |||
| 127 | Elf_Section export_gpl_sec; | 127 | Elf_Section export_gpl_sec; |
| 128 | Elf_Section export_unused_gpl_sec; | 128 | Elf_Section export_unused_gpl_sec; |
| 129 | Elf_Section export_gpl_future_sec; | 129 | Elf_Section export_gpl_future_sec; |
| 130 | const char *strtab; | 130 | char *strtab; |
| 131 | char *modinfo; | 131 | char *modinfo; |
| 132 | unsigned int modinfo_len; | 132 | unsigned int modinfo_len; |
| 133 | 133 | ||
