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

Showing the changes to scripts/mod (2 of 2 files). Show all

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
22static int all_versions = 0;22static int all_versions = 0;
23/* If we are modposting external module set to 1 */23/* If we are modposting external module set to 1 */
24static int external_module = 0;24static int external_module = 0;
25/* How a symbol is exported */
26enum export {export_plain, export_gpl, export_gpl_future, export_unknown};
25 27
26void fatal(const char *fmt, ...)28void fatal(const char *fmt, ...)
27{29{
@@ -118,6 +120,7 @@ struct symbol { · 90 unmodified lines
118 unsigned int kernel:1; /* 1 if symbol is from kernel120 unsigned int kernel:1; /* 1 if symbol is from kernel
119 * (only for external modules) **/121 * (only for external modules) **/
120 unsigned int preloaded:1; /* 1 if symbol from Module.symvers */122 unsigned int preloaded:1; /* 1 if symbol from Module.symvers */
123 enum export export; /* Type of export */
121 char name[0];124 char name[0];
122};125};
123 126
@@ -153,7 +156,8 @@ static struct symbol *alloc_symbol(const char *name, unsigned int weak, · 29 unmodified lines
153}156}
154 157
155/* For the hash of exported symbols */158/* For the hash of exported symbols */
156static struct symbol *new_symbol(const char *name, struct module *module)159static struct symbol *new_symbol(const char *name, struct module *module,
160 enum export export)
157{161{
158 unsigned int hash;162 unsigned int hash;
159 struct symbol *new;163 struct symbol *new;
@@ -161,6 +165,7 @@ static struct symbol *new_symbol(const char *name, struct module *module) · 1 unmodified line
161 hash = tdb_hash(name) % SYMBOL_HASH_SIZE;165 hash = tdb_hash(name) % SYMBOL_HASH_SIZE;
162 new = symbolhash[hash] = alloc_symbol(name, 0, symbolhash[hash]);166 new = symbolhash[hash] = alloc_symbol(name, 0, symbolhash[hash]);
163 new->module = module;167 new->module = module;
168 new->export = export;
164 return new;169 return new;
165}170}
166 171
@@ -179,16 +184,55 @@ static struct symbol *find_symbol(const char *name) · 12 unmodified lines
179 return NULL;184 return NULL;
180}185}
181 186
187static 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
198static const char *export_str(enum export ex)
199{
200 return export_list[ex].str;
201}
202
203static 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
213static 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
182/**225/**
183 * Add an exported symbol - it may have already been added without a226 * Add an exported symbol - it may have already been added without a
184 * CRC, in this case just update the CRC227 * CRC, in this case just update the CRC
185 **/228 **/
186static struct symbol *sym_add_exported(const char *name, struct module *mod)229static struct symbol *sym_add_exported(const char *name, struct module *mod,
230 enum export export)
187{231{
188 struct symbol *s = find_symbol(name);232 struct symbol *s = find_symbol(name);
189 233
190 if (!s) {234 if (!s) {
191 s = new_symbol(name, mod);235 s = new_symbol(name, mod, export);
192 } else {236 } else {
193 if (!s->preloaded) {237 if (!s->preloaded) {
194 warn("%s: '%s' exported twice. Previous export "238 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
200 s->preloaded = 0;244 s->preloaded = 0;
201 s->vmlinux = is_vmlinux(mod->name);245 s->vmlinux = is_vmlinux(mod->name);
202 s->kernel = 0;246 s->kernel = 0;
247 s->export = export;
203 return s;248 return s;
204}249}
205 250
206static void sym_update_crc(const char *name, struct module *mod,251static void sym_update_crc(const char *name, struct module *mod,
207 unsigned int crc)252 unsigned int crc, enum export export)
208{253{
209 struct symbol *s = find_symbol(name);254 struct symbol *s = find_symbol(name);
210 255
211 if (!s)256 if (!s)
212 s = new_symbol(name, mod);257 s = new_symbol(name, mod, export);
213 s->crc = crc;258 s->crc = crc;
214 s->crc_valid = 1;259 s->crc_valid = 1;
215}260}
@@ -309,13 +354,21 @@ static void parse_elf(struct elf_info *info, const char *filename) · 93 unmodified lines
309 for (i = 1; i < hdr->e_shnum; i++) {354 for (i = 1; i < hdr->e_shnum; i++) {
310 const char *secstrings355 const char *secstrings
311 = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;356 = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
357 const char *secname;
312 358
313 if (sechdrs[i].sh_offset > info->size)359 if (sechdrs[i].sh_offset > info->size)
314 goto truncated;360 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) {
316 info->modinfo = (void *)hdr + sechdrs[i].sh_offset;363 info->modinfo = (void *)hdr + sechdrs[i].sh_offset;
317 info->modinfo_len = sechdrs[i].sh_size;364 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
319 if (sechdrs[i].sh_type != SHT_SYMTAB)372 if (sechdrs[i].sh_type != SHT_SYMTAB)
320 continue;373 continue;
321 374
@@ -353,6 +406,7 @@ static void handle_modversions(struct module *mod, struct elf_info *info, · 31 unmodified lines
353 Elf_Sym *sym, const char *symname)406 Elf_Sym *sym, const char *symname)
354{407{
355 unsigned int crc;408 unsigned int crc;
409 enum export export = export_from_sec(info, sym->st_shndx);
356 410
357 switch (sym->st_shndx) {411 switch (sym->st_shndx) {
358 case SHN_COMMON:412 case SHN_COMMON:
@@ -362,7 +416,8 @@ static void handle_modversions(struct module *mod, struct elf_info *info, · 3 unmodified lines
362 /* CRC'd symbol */416 /* CRC'd symbol */
363 if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) {417 if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) {
364 crc = (unsigned int) sym->st_value;418 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);
366 }421 }
367 break;422 break;
368 case SHN_UNDEF:423 case SHN_UNDEF:
@@ -406,7 +461,8 @@ static void handle_modversions(struct module *mod, struct elf_info *info, · 37 unmodified lines
406 default:461 default:
407 /* All exported symbols */462 /* All exported symbols */
408 if (memcmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) {463 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);
410 }466 }
411 if (strcmp(symname, MODULE_SYMBOL_PREFIX "init_module") == 0)467 if (strcmp(symname, MODULE_SYMBOL_PREFIX "init_module") == 0)
412 mod->has_init = 1;468 mod->has_init = 1;
@@ -1146,6 +1202,9 @@ static void write_if_changed(struct buffer *b, const char *fname) · 733 unmodified lines
1146 fclose(file);1202 fclose(file);
1147}1203}
1148 1204
1205/* parse Module.symvers file. line format:
1206 * 0x12345678<tab>symbol<tab>module[<tab>export]
1207 **/
1149static void read_dump(const char *fname, unsigned int kernel)1208static void read_dump(const char *fname, unsigned int kernel)
1150{1209{
1151 unsigned long size, pos = 0;1210 unsigned long size, pos = 0;
@@ -1157,7 +1216,7 @@ static void read_dump(const char *fname, unsigned int kernel) · 5 unmodified lines
1157 return;1216 return;
1158 1217
1159 while ((line = get_next_line(&pos, file, size))) {1218 while ((line = get_next_line(&pos, file, size))) {
1160 char *symname, *modname, *d;1219 char *symname, *modname, *d, *export;
1161 unsigned int crc;1220 unsigned int crc;
1162 struct module *mod;1221 struct module *mod;
1163 struct symbol *s;1222 struct symbol *s;
@@ -1168,8 +1227,9 @@ static void read_dump(const char *fname, unsigned int kernel) · 4 unmodified lines
1168 if (!(modname = strchr(symname, '\t')))1227 if (!(modname = strchr(symname, '\t')))
1169 goto fail;1228 goto fail;
1170 *modname++ = '\0';1229 *modname++ = '\0';
1171 if (strchr(modname, '\t'))1230 if (!(export = strchr(modname, '\t')))
1172 goto fail;1231 *export++ = '\0';
1232
1173 crc = strtoul(line, &d, 16);1233 crc = strtoul(line, &d, 16);
1174 if (*symname == '\0' || *modname == '\0' || *d != '\0')1234 if (*symname == '\0' || *modname == '\0' || *d != '\0')
1175 goto fail;1235 goto fail;
@@ -1181,10 +1241,10 @@ static void read_dump(const char *fname, unsigned int kernel) · 5 unmodified lines
1181 mod = new_module(NOFAIL(strdup(modname)));1241 mod = new_module(NOFAIL(strdup(modname)));
1182 mod->skip = 1;1242 mod->skip = 1;
1183 }1243 }
1184 s = sym_add_exported(symname, mod);1244 s = sym_add_exported(symname, mod, export_no(export));
1185 s->kernel = kernel;1245 s->kernel = kernel;
1186 s->preloaded = 1;1246 s->preloaded = 1;
1187 sym_update_crc(symname, mod, crc);1247 sym_update_crc(symname, mod, crc, export_no(export));
1188 }1248 }
1189 return;1249 return;
1190fail:1250fail:
@@ -1214,9 +1274,10 @@ static void write_dump(const char *fname) · 23 unmodified lines
1214 symbol = symbolhash[n];1274 symbol = symbolhash[n];
1215 while (symbol) {1275 while (symbol) {
1216 if (dump_sym(symbol))1276 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",
1218 symbol->crc, symbol->name,1278 symbol->crc, symbol->name,
1219 symbol->module->name);1279 symbol->module->name,
1280 export_str(symbol->export));
1220 symbol = symbol->next;1281 symbol = symbol->next;
1221 }1282 }
1222 }1283 }
scripts/mod/modpost.h+3−0
@@ -115,6 +115,9 @@ struct elf_info { · 114 unmodified lines
115 Elf_Shdr *sechdrs;115 Elf_Shdr *sechdrs;
116 Elf_Sym *symtab_start;116 Elf_Sym *symtab_start;
117 Elf_Sym *symtab_stop;117 Elf_Sym *symtab_stop;
118 Elf_Section export_sec;
119 Elf_Section export_gpl_sec;
120 Elf_Section export_gpl_future_sec;
118 const char *strtab;121 const char *strtab;
119 char *modinfo;122 char *modinfo;
120 unsigned int modinfo_len;123 unsigned int modinfo_len;