aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/mod/modpost.c
diff options
context:
space:
mode:
Diffstat (limited to 'scripts/mod/modpost.c')
-rw-r--r--scripts/mod/modpost.c177
1 files changed, 158 insertions, 19 deletions
diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
index d0f86ed43f7a..0dd16177642d 100644
--- a/scripts/mod/modpost.c
+++ b/scripts/mod/modpost.c
@@ -13,6 +13,7 @@
13 13
14#include <ctype.h> 14#include <ctype.h>
15#include "modpost.h" 15#include "modpost.h"
16#include "../../include/linux/license.h"
16 17
17/* Are we using CONFIG_MODVERSIONS? */ 18/* Are we using CONFIG_MODVERSIONS? */
18int modversions = 0; 19int modversions = 0;
@@ -22,6 +23,8 @@ int have_vmlinux = 0;
22static int all_versions = 0; 23static int all_versions = 0;
23/* If we are modposting external module set to 1 */ 24/* If we are modposting external module set to 1 */
24static int external_module = 0; 25static int external_module = 0;
26/* How a symbol is exported */
27enum export {export_plain, export_gpl, export_gpl_future, export_unknown};
25 28
26void fatal(const char *fmt, ...) 29void fatal(const char *fmt, ...)
27{ 30{
@@ -97,6 +100,7 @@ static struct module *new_module(char *modname)
97 100
98 /* add to list */ 101 /* add to list */
99 mod->name = p; 102 mod->name = p;
103 mod->gpl_compatible = -1;
100 mod->next = modules; 104 mod->next = modules;
101 modules = mod; 105 modules = mod;
102 106
@@ -118,6 +122,7 @@ struct symbol {
118 unsigned int kernel:1; /* 1 if symbol is from kernel 122 unsigned int kernel:1; /* 1 if symbol is from kernel
119 * (only for external modules) **/ 123 * (only for external modules) **/
120 unsigned int preloaded:1; /* 1 if symbol from Module.symvers */ 124 unsigned int preloaded:1; /* 1 if symbol from Module.symvers */
125 enum export export; /* Type of export */
121 char name[0]; 126 char name[0];
122}; 127};
123 128
@@ -153,7 +158,8 @@ static struct symbol *alloc_symbol(const char *name, unsigned int weak,
153} 158}
154 159
155/* For the hash of exported symbols */ 160/* For the hash of exported symbols */
156static struct symbol *new_symbol(const char *name, struct module *module) 161static struct symbol *new_symbol(const char *name, struct module *module,
162 enum export export)
157{ 163{
158 unsigned int hash; 164 unsigned int hash;
159 struct symbol *new; 165 struct symbol *new;
@@ -161,6 +167,7 @@ static struct symbol *new_symbol(const char *name, struct module *module)
161 hash = tdb_hash(name) % SYMBOL_HASH_SIZE; 167 hash = tdb_hash(name) % SYMBOL_HASH_SIZE;
162 new = symbolhash[hash] = alloc_symbol(name, 0, symbolhash[hash]); 168 new = symbolhash[hash] = alloc_symbol(name, 0, symbolhash[hash]);
163 new->module = module; 169 new->module = module;
170 new->export = export;
164 return new; 171 return new;
165} 172}
166 173
@@ -179,16 +186,55 @@ static struct symbol *find_symbol(const char *name)
179 return NULL; 186 return NULL;
180} 187}
181 188
189static struct {
190 const char *str;
191 enum export export;
192} export_list[] = {
193 { .str = "EXPORT_SYMBOL", .export = export_plain },
194 { .str = "EXPORT_SYMBOL_GPL", .export = export_gpl },
195 { .str = "EXPORT_SYMBOL_GPL_FUTURE", .export = export_gpl_future },
196 { .str = "(unknown)", .export = export_unknown },
197};
198
199
200static const char *export_str(enum export ex)
201{
202 return export_list[ex].str;
203}
204
205static enum export export_no(const char * s)
206{
207 int i;
208 for (i = 0; export_list[i].export != export_unknown; i++) {
209 if (strcmp(export_list[i].str, s) == 0)
210 return export_list[i].export;
211 }
212 return export_unknown;
213}
214
215static enum export export_from_sec(struct elf_info *elf, Elf_Section sec)
216{
217 if (sec == elf->export_sec)
218 return export_plain;
219 else if (sec == elf->export_gpl_sec)
220 return export_gpl;
221 else if (sec == elf->export_gpl_future_sec)
222 return export_gpl_future;
223 else
224 return export_unknown;
225}
226
182/** 227/**
183 * Add an exported symbol - it may have already been added without a 228 * Add an exported symbol - it may have already been added without a
184 * CRC, in this case just update the CRC 229 * CRC, in this case just update the CRC
185 **/ 230 **/
186static struct symbol *sym_add_exported(const char *name, struct module *mod) 231static struct symbol *sym_add_exported(const char *name, struct module *mod,
232 enum export export)
187{ 233{
188 struct symbol *s = find_symbol(name); 234 struct symbol *s = find_symbol(name);
189 235
190 if (!s) { 236 if (!s) {
191 s = new_symbol(name, mod); 237 s = new_symbol(name, mod, export);
192 } else { 238 } else {
193 if (!s->preloaded) { 239 if (!s->preloaded) {
194 warn("%s: '%s' exported twice. Previous export " 240 warn("%s: '%s' exported twice. Previous export "
@@ -200,16 +246,17 @@ static struct symbol *sym_add_exported(const char *name, struct module *mod)
200 s->preloaded = 0; 246 s->preloaded = 0;
201 s->vmlinux = is_vmlinux(mod->name); 247 s->vmlinux = is_vmlinux(mod->name);
202 s->kernel = 0; 248 s->kernel = 0;
249 s->export = export;
203 return s; 250 return s;
204} 251}
205 252
206static void sym_update_crc(const char *name, struct module *mod, 253static void sym_update_crc(const char *name, struct module *mod,
207 unsigned int crc) 254 unsigned int crc, enum export export)
208{ 255{
209 struct symbol *s = find_symbol(name); 256 struct symbol *s = find_symbol(name);
210 257
211 if (!s) 258 if (!s)
212 s = new_symbol(name, mod); 259 s = new_symbol(name, mod, export);
213 s->crc = crc; 260 s->crc = crc;
214 s->crc_valid = 1; 261 s->crc_valid = 1;
215} 262}
@@ -283,7 +330,7 @@ static void parse_elf(struct elf_info *info, const char *filename)
283 hdr = grab_file(filename, &info->size); 330 hdr = grab_file(filename, &info->size);
284 if (!hdr) { 331 if (!hdr) {
285 perror(filename); 332 perror(filename);
286 abort(); 333 exit(1);
287 } 334 }
288 info->hdr = hdr; 335 info->hdr = hdr;
289 if (info->size < sizeof(*hdr)) 336 if (info->size < sizeof(*hdr))
@@ -309,13 +356,21 @@ static void parse_elf(struct elf_info *info, const char *filename)
309 for (i = 1; i < hdr->e_shnum; i++) { 356 for (i = 1; i < hdr->e_shnum; i++) {
310 const char *secstrings 357 const char *secstrings
311 = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; 358 = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
359 const char *secname;
312 360
313 if (sechdrs[i].sh_offset > info->size) 361 if (sechdrs[i].sh_offset > info->size)
314 goto truncated; 362 goto truncated;
315 if (strcmp(secstrings+sechdrs[i].sh_name, ".modinfo") == 0) { 363 secname = secstrings + sechdrs[i].sh_name;
364 if (strcmp(secname, ".modinfo") == 0) {
316 info->modinfo = (void *)hdr + sechdrs[i].sh_offset; 365 info->modinfo = (void *)hdr + sechdrs[i].sh_offset;
317 info->modinfo_len = sechdrs[i].sh_size; 366 info->modinfo_len = sechdrs[i].sh_size;
318 } 367 } else if (strcmp(secname, "__ksymtab") == 0)
368 info->export_sec = i;
369 else if (strcmp(secname, "__ksymtab_gpl") == 0)
370 info->export_gpl_sec = i;
371 else if (strcmp(secname, "__ksymtab_gpl_future") == 0)
372 info->export_gpl_future_sec = i;
373
319 if (sechdrs[i].sh_type != SHT_SYMTAB) 374 if (sechdrs[i].sh_type != SHT_SYMTAB)
320 continue; 375 continue;
321 376
@@ -353,6 +408,7 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
353 Elf_Sym *sym, const char *symname) 408 Elf_Sym *sym, const char *symname)
354{ 409{
355 unsigned int crc; 410 unsigned int crc;
411 enum export export = export_from_sec(info, sym->st_shndx);
356 412
357 switch (sym->st_shndx) { 413 switch (sym->st_shndx) {
358 case SHN_COMMON: 414 case SHN_COMMON:
@@ -362,7 +418,8 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
362 /* CRC'd symbol */ 418 /* CRC'd symbol */
363 if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) { 419 if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) {
364 crc = (unsigned int) sym->st_value; 420 crc = (unsigned int) sym->st_value;
365 sym_update_crc(symname + strlen(CRC_PFX), mod, crc); 421 sym_update_crc(symname + strlen(CRC_PFX), mod, crc,
422 export);
366 } 423 }
367 break; 424 break;
368 case SHN_UNDEF: 425 case SHN_UNDEF:
@@ -406,7 +463,8 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
406 default: 463 default:
407 /* All exported symbols */ 464 /* All exported symbols */
408 if (memcmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) { 465 if (memcmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) {
409 sym_add_exported(symname + strlen(KSYMTAB_PFX), mod); 466 sym_add_exported(symname + strlen(KSYMTAB_PFX), mod,
467 export);
410 } 468 }
411 if (strcmp(symname, MODULE_SYMBOL_PREFIX "init_module") == 0) 469 if (strcmp(symname, MODULE_SYMBOL_PREFIX "init_module") == 0)
412 mod->has_init = 1; 470 mod->has_init = 1;
@@ -437,13 +495,18 @@ static char *next_string(char *string, unsigned long *secsize)
437 return string; 495 return string;
438} 496}
439 497
440static char *get_modinfo(void *modinfo, unsigned long modinfo_len, 498static char *get_next_modinfo(void *modinfo, unsigned long modinfo_len,
441 const char *tag) 499 const char *tag, char *info)
442{ 500{
443 char *p; 501 char *p;
444 unsigned int taglen = strlen(tag); 502 unsigned int taglen = strlen(tag);
445 unsigned long size = modinfo_len; 503 unsigned long size = modinfo_len;
446 504
505 if (info) {
506 size -= info - (char *)modinfo;
507 modinfo = next_string(info, &size);
508 }
509
447 for (p = modinfo; p; p = next_string(p, &size)) { 510 for (p = modinfo; p; p = next_string(p, &size)) {
448 if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=') 511 if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=')
449 return p + taglen + 1; 512 return p + taglen + 1;
@@ -451,6 +514,13 @@ static char *get_modinfo(void *modinfo, unsigned long modinfo_len,
451 return NULL; 514 return NULL;
452} 515}
453 516
517static char *get_modinfo(void *modinfo, unsigned long modinfo_len,
518 const char *tag)
519
520{
521 return get_next_modinfo(modinfo, modinfo_len, tag, NULL);
522}
523
454/** 524/**
455 * Test if string s ends in string sub 525 * Test if string s ends in string sub
456 * return 0 if match 526 * return 0 if match
@@ -821,6 +891,10 @@ static int init_section_ref_ok(const char *name)
821 ".pci_fixup_final", 891 ".pci_fixup_final",
822 ".pdr", 892 ".pdr",
823 "__param", 893 "__param",
894 "__ex_table",
895 ".fixup",
896 ".smp_locks",
897 ".plt", /* seen on ARCH=um build on x86_64. Harmless */
824 NULL 898 NULL
825 }; 899 };
826 /* Start of section names */ 900 /* Start of section names */
@@ -846,6 +920,8 @@ static int init_section_ref_ok(const char *name)
846 for (s = namelist3; *s; s++) 920 for (s = namelist3; *s; s++)
847 if (strstr(name, *s) != NULL) 921 if (strstr(name, *s) != NULL)
848 return 1; 922 return 1;
923 if (strrcmp(name, ".init") == 0)
924 return 1;
849 return 0; 925 return 0;
850} 926}
851 927
@@ -892,6 +968,10 @@ static int exit_section_ref_ok(const char *name)
892 ".exitcall.exit", 968 ".exitcall.exit",
893 ".eh_frame", 969 ".eh_frame",
894 ".stab", 970 ".stab",
971 "__ex_table",
972 ".fixup",
973 ".smp_locks",
974 ".plt", /* seen on ARCH=um build on x86_64. Harmless */
895 NULL 975 NULL
896 }; 976 };
897 /* Start of section names */ 977 /* Start of section names */
@@ -921,6 +1001,7 @@ static void read_symbols(char *modname)
921{ 1001{
922 const char *symname; 1002 const char *symname;
923 char *version; 1003 char *version;
1004 char *license;
924 struct module *mod; 1005 struct module *mod;
925 struct elf_info info = { }; 1006 struct elf_info info = { };
926 Elf_Sym *sym; 1007 Elf_Sym *sym;
@@ -936,6 +1017,18 @@ static void read_symbols(char *modname)
936 mod->skip = 1; 1017 mod->skip = 1;
937 } 1018 }
938 1019
1020 license = get_modinfo(info.modinfo, info.modinfo_len, "license");
1021 while (license) {
1022 if (license_is_gpl_compatible(license))
1023 mod->gpl_compatible = 1;
1024 else {
1025 mod->gpl_compatible = 0;
1026 break;
1027 }
1028 license = get_next_modinfo(info.modinfo, info.modinfo_len,
1029 "license", license);
1030 }
1031
939 for (sym = info.symtab_start; sym < info.symtab_stop; sym++) { 1032 for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
940 symname = info.strtab + sym->st_name; 1033 symname = info.strtab + sym->st_name;
941 1034
@@ -992,6 +1085,41 @@ void buf_write(struct buffer *buf, const char *s, int len)
992 buf->pos += len; 1085 buf->pos += len;
993} 1086}
994 1087
1088void check_license(struct module *mod)
1089{
1090 struct symbol *s, *exp;
1091
1092 for (s = mod->unres; s; s = s->next) {
1093 const char *basename;
1094 if (mod->gpl_compatible == 1) {
1095 /* GPL-compatible modules may use all symbols */
1096 continue;
1097 }
1098 exp = find_symbol(s->name);
1099 if (!exp || exp->module == mod)
1100 continue;
1101 basename = strrchr(mod->name, '/');
1102 if (basename)
1103 basename++;
1104 switch (exp->export) {
1105 case export_gpl:
1106 fatal("modpost: GPL-incompatible module %s "
1107 "uses GPL-only symbol '%s'\n",
1108 basename ? basename : mod->name,
1109 exp->name);
1110 break;
1111 case export_gpl_future:
1112 warn("modpost: GPL-incompatible module %s "
1113 "uses future GPL-only symbol '%s'\n",
1114 basename ? basename : mod->name,
1115 exp->name);
1116 break;
1117 case export_plain: /* ignore */ break;
1118 case export_unknown: /* ignore */ break;
1119 }
1120 }
1121}
1122
995/** 1123/**
996 * Header for the generated file 1124 * Header for the generated file
997 **/ 1125 **/
@@ -1142,6 +1270,9 @@ static void write_if_changed(struct buffer *b, const char *fname)
1142 fclose(file); 1270 fclose(file);
1143} 1271}
1144 1272
1273/* parse Module.symvers file. line format:
1274 * 0x12345678<tab>symbol<tab>module[<tab>export]
1275 **/
1145static void read_dump(const char *fname, unsigned int kernel) 1276static void read_dump(const char *fname, unsigned int kernel)
1146{ 1277{
1147 unsigned long size, pos = 0; 1278 unsigned long size, pos = 0;
@@ -1153,7 +1284,7 @@ static void read_dump(const char *fname, unsigned int kernel)
1153 return; 1284 return;
1154 1285
1155 while ((line = get_next_line(&pos, file, size))) { 1286 while ((line = get_next_line(&pos, file, size))) {
1156 char *symname, *modname, *d; 1287 char *symname, *modname, *d, *export;
1157 unsigned int crc; 1288 unsigned int crc;
1158 struct module *mod; 1289 struct module *mod;
1159 struct symbol *s; 1290 struct symbol *s;
@@ -1164,8 +1295,9 @@ static void read_dump(const char *fname, unsigned int kernel)
1164 if (!(modname = strchr(symname, '\t'))) 1295 if (!(modname = strchr(symname, '\t')))
1165 goto fail; 1296 goto fail;
1166 *modname++ = '\0'; 1297 *modname++ = '\0';
1167 if (strchr(modname, '\t')) 1298 if ((export = strchr(modname, '\t')) != NULL)
1168 goto fail; 1299 *export++ = '\0';
1300
1169 crc = strtoul(line, &d, 16); 1301 crc = strtoul(line, &d, 16);
1170 if (*symname == '\0' || *modname == '\0' || *d != '\0') 1302 if (*symname == '\0' || *modname == '\0' || *d != '\0')
1171 goto fail; 1303 goto fail;
@@ -1177,10 +1309,10 @@ static void read_dump(const char *fname, unsigned int kernel)
1177 mod = new_module(NOFAIL(strdup(modname))); 1309 mod = new_module(NOFAIL(strdup(modname)));
1178 mod->skip = 1; 1310 mod->skip = 1;
1179 } 1311 }
1180 s = sym_add_exported(symname, mod); 1312 s = sym_add_exported(symname, mod, export_no(export));
1181 s->kernel = kernel; 1313 s->kernel = kernel;
1182 s->preloaded = 1; 1314 s->preloaded = 1;
1183 sym_update_crc(symname, mod, crc); 1315 sym_update_crc(symname, mod, crc, export_no(export));
1184 } 1316 }
1185 return; 1317 return;
1186fail: 1318fail:
@@ -1210,9 +1342,10 @@ static void write_dump(const char *fname)
1210 symbol = symbolhash[n]; 1342 symbol = symbolhash[n];
1211 while (symbol) { 1343 while (symbol) {
1212 if (dump_sym(symbol)) 1344 if (dump_sym(symbol))
1213 buf_printf(&buf, "0x%08x\t%s\t%s\n", 1345 buf_printf(&buf, "0x%08x\t%s\t%s\t%s\n",
1214 symbol->crc, symbol->name, 1346 symbol->crc, symbol->name,
1215 symbol->module->name); 1347 symbol->module->name,
1348 export_str(symbol->export));
1216 symbol = symbol->next; 1349 symbol = symbol->next;
1217 } 1350 }
1218 } 1351 }
@@ -1263,6 +1396,12 @@ int main(int argc, char **argv)
1263 for (mod = modules; mod; mod = mod->next) { 1396 for (mod = modules; mod; mod = mod->next) {
1264 if (mod->skip) 1397 if (mod->skip)
1265 continue; 1398 continue;
1399 check_license(mod);
1400 }
1401
1402 for (mod = modules; mod; mod = mod->next) {
1403 if (mod->skip)
1404 continue;
1266 1405
1267 buf.pos = 0; 1406 buf.pos = 0;
1268 1407