History

kbuild: export-type enhancement to modpost.c

This patch provides the ability to identify the export-type of each exported symbols in Module.symvers. NOTE: It updates the Module.symvers file with the additional information as shown below. 0x0f8b92af platform_device_add_resources vmlinux EXPORT_SYMBOL_GPL 0xcf7efb2a ethtool_op_set_tx_csum vmlinux EXPORT_SYMBOL

Ram Pai committed 20 years ago

Commit bd5cbce1 parent 031ecc62 files · +80 −16Browse files

Unified · Split

2 files
  1. scripts/mod/modpost.c +77 −16
  2. scripts/mod/modpost.h +3 −0
scripts/mod/modpost.c+77−16
@@ -22,6 +22,8 @@ int have_vmlinux = 0; · 21 unmodified lines
2222 static int all_versions = 0;
2323 /* If we are modposting external module set to 1 */
2424 static int external_module = 0;
25+/* How a symbol is exported */
26+enum export {export_plain, export_gpl, export_gpl_future, export_unknown};
2527
2628 void fatal(const char *fmt, ...)
2729 {
@@ -118,6 +120,7 @@ struct symbol { · 90 unmodified lines
118120 unsigned int kernel:1; /* 1 if symbol is from kernel
119121 * (only for external modules) **/
120122 unsigned int preloaded:1; /* 1 if symbol from Module.symvers */
123+ enum export export; /* Type of export */
121124 char name[0];
122125 };
123126
@@ -153,7 +156,8 @@ static struct symbol *alloc_symbol(const char *name, unsigned int weak, · 29 unmodified lines
153156 }
154157
155158 /* For the hash of exported symbols */
156−static struct symbol *new_symbol(const char *name, struct module *module)
159+static struct symbol *new_symbol(const char *name, struct module *module,
160+ enum export export)
157161 {
158162 unsigned int hash;
159163 struct symbol *new;
@@ -161,6 +165,7 @@ static struct symbol *new_symbol(const char *name, struct module *module) · 1 unmodified line
161165 hash = tdb_hash(name) % SYMBOL_HASH_SIZE;
162166 new = symbolhash[hash] = alloc_symbol(name, 0, symbolhash[hash]);
163167 new->module = module;
168+ new->export = export;
164169 return new;
165170 }
166171
@@ -179,16 +184,55 @@ static struct symbol *find_symbol(const char *name) · 12 unmodified lines
179184 return NULL;
180185 }
181186
187+static struct {
188+ const char *str;
189+ enum export export;
190+} export_list[] = {
191+ { .str = "EXPORT_SYMBOL", .export = export_plain },
192+ { .str = "EXPORT_SYMBOL_GPL", .export = export_gpl },
193+ { .str = "EXPORT_SYMBOL_GPL_FUTURE", .export = export_gpl_future },
194+ { .str = "(unknown)", .export = export_unknown },
195+};
196+
197+
198+static const char *export_str(enum export ex)
199+{
200+ return export_list[ex].str;
201+}
202+
203+static enum export export_no(const char * s)
204+{
205+ int i;
206+ for (i = 0; export_list[i].export != export_unknown; i++) {
207+ if (strcmp(export_list[i].str, s) == 0)
208+ return export_list[i].export;
209+ }
210+ return export_unknown;
211+}
212+
213+static enum export export_from_sec(struct elf_info *elf, Elf_Section sec)
214+{
215+ if (sec == elf->export_sec)
216+ return export_plain;
217+ else if (sec == elf->export_gpl_sec)
218+ return export_gpl;
219+ else if (sec == elf->export_gpl_future_sec)
220+ return export_gpl_future;
221+ else
222+ return export_unknown;
223+}
224+
182225 /**
183226 * Add an exported symbol - it may have already been added without a
184227 * CRC, in this case just update the CRC
185228 **/
186−static struct symbol *sym_add_exported(const char *name, struct module *mod)
229+static struct symbol *sym_add_exported(const char *name, struct module *mod,
230+ enum export export)
187231 {
188232 struct symbol *s = find_symbol(name);
189233
190234 if (!s) {
191− s = new_symbol(name, mod);
235+ s = new_symbol(name, mod, export);
192236 } else {
193237 if (!s->preloaded) {
194238 warn("%s: '%s' exported twice. Previous export "
@@ -200,16 +244,17 @@ static struct symbol *sym_add_exported(const char *name, struct module *mod) · 5 unmodified lines
200244 s->preloaded = 0;
201245 s->vmlinux = is_vmlinux(mod->name);
202246 s->kernel = 0;
247+ s->export = export;
203248 return s;
204249 }
205250
206251 static void sym_update_crc(const char *name, struct module *mod,
207− unsigned int crc)
252+ unsigned int crc, enum export export)
208253 {
209254 struct symbol *s = find_symbol(name);
210255
211256 if (!s)
212− s = new_symbol(name, mod);
257+ s = new_symbol(name, mod, export);
213258 s->crc = crc;
214259 s->crc_valid = 1;
215260 }
@@ -309,13 +354,21 @@ static void parse_elf(struct elf_info *info, const char *filename) · 93 unmodified lines
309354 for (i = 1; i < hdr->e_shnum; i++) {
310355 const char *secstrings
311356 = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
357+ const char *secname;
312358
313359 if (sechdrs[i].sh_offset > info->size)
314360 goto truncated;
315− if (strcmp(secstrings+sechdrs[i].sh_name, ".modinfo") == 0) {
361+ secname = secstrings + sechdrs[i].sh_name;
362+ if (strcmp(secname, ".modinfo") == 0) {
316363 info->modinfo = (void *)hdr + sechdrs[i].sh_offset;
317364 info->modinfo_len = sechdrs[i].sh_size;
318− }
365+ } else if (strcmp(secname, "__ksymtab") == 0)
366+ info->export_sec = i;
367+ else if (strcmp(secname, "__ksymtab_gpl") == 0)
368+ info->export_gpl_sec = i;
369+ else if (strcmp(secname, "__ksymtab_gpl_future") == 0)
370+ info->export_gpl_future_sec = i;
371+
319372 if (sechdrs[i].sh_type != SHT_SYMTAB)
320373 continue;
321374
@@ -353,6 +406,7 @@ static void handle_modversions(struct module *mod, struct elf_info *info, · 31 unmodified lines
353406 Elf_Sym *sym, const char *symname)
354407 {
355408 unsigned int crc;
409+ enum export export = export_from_sec(info, sym->st_shndx);
356410
357411 switch (sym->st_shndx) {
358412 case SHN_COMMON:
@@ -362,7 +416,8 @@ static void handle_modversions(struct module *mod, struct elf_info *info, · 3 unmodified lines
362416 /* CRC'd symbol */
363417 if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) {
364418 crc = (unsigned int) sym->st_value;
365− sym_update_crc(symname + strlen(CRC_PFX), mod, crc);
419+ sym_update_crc(symname + strlen(CRC_PFX), mod, crc,
420+ export);
366421 }
367422 break;
368423 case SHN_UNDEF:
@@ -406,7 +461,8 @@ static void handle_modversions(struct module *mod, struct elf_info *info, · 37 unmodified lines
406461 default:
407462 /* All exported symbols */
408463 if (memcmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) {
409− sym_add_exported(symname + strlen(KSYMTAB_PFX), mod);
464+ sym_add_exported(symname + strlen(KSYMTAB_PFX), mod,
465+ export);
410466 }
411467 if (strcmp(symname, MODULE_SYMBOL_PREFIX "init_module") == 0)
412468 mod->has_init = 1;
@@ -1146,6 +1202,9 @@ static void write_if_changed(struct buffer *b, const char *fname) · 733 unmodified lines
11461202 fclose(file);
11471203 }
11481204
1205+/* parse Module.symvers file. line format:
1206+ * 0x12345678<tab>symbol<tab>module[<tab>export]
1207+ **/
11491208 static void read_dump(const char *fname, unsigned int kernel)
11501209 {
11511210 unsigned long size, pos = 0;
@@ -1157,7 +1216,7 @@ static void read_dump(const char *fname, unsigned int kernel) · 5 unmodified lines
11571216 return;
11581217
11591218 while ((line = get_next_line(&pos, file, size))) {
1160− char *symname, *modname, *d;
1219+ char *symname, *modname, *d, *export;
11611220 unsigned int crc;
11621221 struct module *mod;
11631222 struct symbol *s;
@@ -1168,8 +1227,9 @@ static void read_dump(const char *fname, unsigned int kernel) · 4 unmodified lines
11681227 if (!(modname = strchr(symname, '\t')))
11691228 goto fail;
11701229 *modname++ = '\0';
1171− if (strchr(modname, '\t'))
1172− goto fail;
1230+ if (!(export = strchr(modname, '\t')))
1231+ *export++ = '\0';
1232+
11731233 crc = strtoul(line, &d, 16);
11741234 if (*symname == '\0' || *modname == '\0' || *d != '\0')
11751235 goto fail;
@@ -1181,10 +1241,10 @@ static void read_dump(const char *fname, unsigned int kernel) · 5 unmodified lines
11811241 mod = new_module(NOFAIL(strdup(modname)));
11821242 mod->skip = 1;
11831243 }
1184− s = sym_add_exported(symname, mod);
1244+ s = sym_add_exported(symname, mod, export_no(export));
11851245 s->kernel = kernel;
11861246 s->preloaded = 1;
1187− sym_update_crc(symname, mod, crc);
1247+ sym_update_crc(symname, mod, crc, export_no(export));
11881248 }
11891249 return;
11901250 fail:
@@ -1214,9 +1274,10 @@ static void write_dump(const char *fname) · 23 unmodified lines
12141274 symbol = symbolhash[n];
12151275 while (symbol) {
12161276 if (dump_sym(symbol))
1217− buf_printf(&buf, "0x%08x\t%s\t%s\n",
1277+ buf_printf(&buf, "0x%08x\t%s\t%s\t%s\n",
12181278 symbol->crc, symbol->name,
1219− symbol->module->name);
1279+ symbol->module->name,
1280+ export_str(symbol->export));
12201281 symbol = symbol->next;
12211282 }
12221283 }
scripts/mod/modpost.h+3−0
@@ -115,6 +115,9 @@ struct elf_info { · 114 unmodified lines
115115 Elf_Shdr *sechdrs;
116116 Elf_Sym *symtab_start;
117117 Elf_Sym *symtab_stop;
118+ Elf_Section export_sec;
119+ Elf_Section export_gpl_sec;
120+ Elf_Section export_gpl_future_sec;
118121 const char *strtab;
119122 char *modinfo;
120123 unsigned int modinfo_len;