History

Merge master.kernel.org:/pub/scm/linux/kernel/git/sam/kbuild

* master.kernel.org:/pub/scm/linux/kernel/git/sam/kbuild: (46 commits) kbuild: remove obsoleted scripts/reference_* files kbuild: fix make help & make *pkg kconfig: fix time ordering of writes to .kconfig.d and include/linux/autoconf.h Kconfig: remove the CONFIG_CC_ALIGN_* options kbuild: add -fverbose-asm to i386 Makefile kbuild: clean-up genksyms kbuild: Lindent genksyms.c kbuild: fix genksyms build error kbuild: in makefile.txt note that Makefile is preferred name for kbuild files kbuild: replace PHONY with FORCE kbuild: Fix bug in crc symbol generating of kernel and modules kbuild: change kbuild to not rely on incorrect GNU make behavior kbuild: when warning symbols exported twice now tell user this is the problem kbuild: fix make dir/file.xx when asm symlink is missing kbuild: in the section mismatch check try harder to find symbols kbuild: fix section mismatch check for unwind on IA64 kbuild: kill false positives from section mismatch warnings for powerpc kbuild: kill trailing whitespace in modpost & friends kbuild: small update of allnoconfig description kbuild: make namespace.pl CROSS_COMPILE happy ... Trivial conflict in arch/ppc/boot/Makefile manually fixed up

Linus Torvalds committed 20 years ago

Commit 2e1ca212 parents 315ab19 eae0f5352 files · +1500 −1259Browse files

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

Unified · Split

5 files
  1. scripts/mod/file2alias.c +8 −9
  2. scripts/mod/mk_elfconfig.c +2 −2
  3. scripts/mod/modpost.c +562 −136
  4. scripts/mod/modpost.h +20 −5
  5. scripts/mod/sumversion.c +15 −17
scripts/mod/file2alias.c+8−9
@@ -34,7 +34,7 @@ typedef uint16_t __u16; · 33 unmodified lines
3434 typedef unsigned char __u8;
3535
3636 /* Big exception to the "don't include kernel headers into userspace, which
37− * even potentially has different endianness and word sizes, since
37+ * even potentially has different endianness and word sizes, since
3838 * we handle those differences explicitly below */
3939 #include "../../include/linux/mod_devicetable.h"
4040 #include "../../include/linux/input.h"
@@ -153,8 +153,8 @@ static void do_usb_table(void *symval, unsigned long size, · 112 unmodified lines
153153 const unsigned long id_size = sizeof(struct usb_device_id);
154154
155155 if (size % id_size || size < id_size) {
156− fprintf(stderr, "*** Warning: %s ids %lu bad size "
157− "(each on %lu)\n", mod->name, size, id_size);
156+ warn("%s ids %lu bad size "
157+ "(each on %lu)\n", mod->name, size, id_size);
158158 }
159159 /* Leave last one: it's the terminator. */
160160 size -= id_size;
@@ -217,9 +217,8 @@ static int do_pci_entry(const char *filename, · 56 unmodified lines
217217 if ((baseclass_mask != 0 && baseclass_mask != 0xFF)
218218 || (subclass_mask != 0 && subclass_mask != 0xFF)
219219 || (interface_mask != 0 && interface_mask != 0xFF)) {
220− fprintf(stderr,
221− "*** Warning: Can't handle masks in %s:%04X\n",
222− filename, id->class_mask);
220+ warn("Can't handle masks in %s:%04X\n",
221+ filename, id->class_mask);
223222 return 0;
224223 }
225224
@@ -229,7 +228,7 @@ static int do_pci_entry(const char *filename, · 3 unmodified lines
229228 return 1;
230229 }
231230
232−/* looks like: "ccw:tNmNdtNdmN" */
231+/* looks like: "ccw:tNmNdtNdmN" */
233232 static int do_ccw_entry(const char *filename,
234233 struct ccw_device_id *id, char *alias)
235234 {
@@ -445,8 +444,8 @@ static void do_table(void *symval, unsigned long size, · 209 unmodified lines
445444 int (*do_entry)(const char *, void *entry, char *alias) = function;
446445
447446 if (size % id_size || size < id_size) {
448− fprintf(stderr, "*** Warning: %s ids %lu bad size "
449− "(each on %lu)\n", mod->name, size, id_size);
447+ warn("%s ids %lu bad size "
448+ "(each on %lu)\n", mod->name, size, id_size);
450449 }
451450 /* Leave last one: it's the terminator. */
452451 size -= id_size;
scripts/mod/mk_elfconfig.c+2−2
@@ -6,7 +6,7 @@ · 5 unmodified lines
66 int
77 main(int argc, char **argv)
88 {
9− unsigned char ei[EI_NIDENT];
9+ unsigned char ei[EI_NIDENT];
1010 union { short s; char c[2]; } endian_test;
1111
1212 if (argc != 2) {
@@ -57,7 +57,7 @@ main(int argc, char **argv) · 44 unmodified lines
5757
5858 if ((strcmp(argv[1], "v850") == 0) || (strcmp(argv[1], "h8300") == 0))
5959 printf("#define MODULE_SYMBOL_PREFIX \"_\"\n");
60− else
60+ else
6161 printf("#define MODULE_SYMBOL_PREFIX \"\"\n");
6262
6363 return 0;
scripts/mod/modpost.c+562−136
@@ -2,7 +2,7 @@ · 1 unmodified line
22 *
33 * Copyright 2003 Kai Germaschewski
44 * Copyright 2002-2004 Rusty Russell, IBM Corporation
5− *
5+ * Copyright 2006 Sam Ravnborg
66 * Based in part on module-init-tools/depmod.c,file2alias
77 *
88 * This software may be used and distributed according to the terms
@@ -20,9 +20,10 @@ int modversions = 0; · 11 unmodified lines
2020 int have_vmlinux = 0;
2121 /* Is CONFIG_MODULE_SRCVERSION_ALL set? */
2222 static int all_versions = 0;
23+/* If we are modposting external module set to 1 */
24+static int external_module = 0;
2325
24−void
25−fatal(const char *fmt, ...)
26+void fatal(const char *fmt, ...)
2627 {
2728 va_list arglist;
2829
@@ -35,8 +36,7 @@ fatal(const char *fmt, ...) · 6 unmodified lines
3536 exit(1);
3637 }
3738
38−void
39−warn(const char *fmt, ...)
39+void warn(const char *fmt, ...)
4040 {
4141 va_list arglist;
4242
@@ -47,6 +47,18 @@ warn(const char *fmt, ...) · 4 unmodified lines
4747 va_end(arglist);
4848 }
4949
50+static int is_vmlinux(const char *modname)
51+{
52+ const char *myname;
53+
54+ if ((myname = strrchr(modname, '/')))
55+ myname++;
56+ else
57+ myname = modname;
58+
59+ return strcmp(myname, "vmlinux") == 0;
60+}
61+
5062 void *do_nofail(void *ptr, const char *expr)
5163 {
5264 if (!ptr) {
@@ -59,8 +71,7 @@ void *do_nofail(void *ptr, const char *expr) · 6 unmodified lines
5971
6072 static struct module *modules;
6173
62−struct module *
63−find_module(char *modname)
74+static struct module *find_module(char *modname)
6475 {
6576 struct module *mod;
6677
@@ -70,12 +81,11 @@ find_module(char *modname) · 3 unmodified lines
7081 return mod;
7182 }
7283
73−struct module *
74−new_module(char *modname)
84+static struct module *new_module(char *modname)
7585 {
7686 struct module *mod;
7787 char *p, *s;
78−
88+
7989 mod = NOFAIL(malloc(sizeof(*mod)));
8090 memset(mod, 0, sizeof(*mod));
8191 p = NOFAIL(strdup(modname));
@@ -104,6 +114,10 @@ struct symbol { · 22 unmodified lines
104114 unsigned int crc;
105115 int crc_valid;
106116 unsigned int weak:1;
117+ unsigned int vmlinux:1; /* 1 if symbol is defined in vmlinux */
118+ unsigned int kernel:1; /* 1 if symbol is from kernel
119+ * (only for external modules) **/
120+ unsigned int preloaded:1; /* 1 if symbol from Module.symvers */
107121 char name[0];
108122 };
109123
@@ -122,11 +136,12 @@ static inline unsigned int tdb_hash(const char *name) · 12 unmodified lines
122136 return (1103515243 * value + 12345);
123137 }
124138
125−/* Allocate a new symbols for use in the hash of exported symbols or
126− * the list of unresolved symbols per module */
127−
128−struct symbol *
129−alloc_symbol(const char *name, unsigned int weak, struct symbol *next)
139+/**
140+ * Allocate a new symbols for use in the hash of exported symbols or
141+ * the list of unresolved symbols per module
142+ **/
143+static struct symbol *alloc_symbol(const char *name, unsigned int weak,
144+ struct symbol *next)
130145 {
131146 struct symbol *s = NOFAIL(malloc(sizeof(*s) + strlen(name) + 1));
132147
@@ -138,9 +153,7 @@ alloc_symbol(const char *name, unsigned int weak, struct symbol *next) · 5 unmodified lines
138153 }
139154
140155 /* For the hash of exported symbols */
141−
142−void
143−new_symbol(const char *name, struct module *module, unsigned int *crc)
156+static struct symbol *new_symbol(const char *name, struct module *module)
144157 {
145158 unsigned int hash;
146159 struct symbol *new;
@@ -148,14 +161,10 @@ new_symbol(const char *name, struct module *module, unsigned int *crc) · 1 unmodified line
148161 hash = tdb_hash(name) % SYMBOL_HASH_SIZE;
149162 new = symbolhash[hash] = alloc_symbol(name, 0, symbolhash[hash]);
150163 new->module = module;
151− if (crc) {
152− new->crc = *crc;
153− new->crc_valid = 1;
154− }
164+ return new;
155165 }
156166
157−struct symbol *
158−find_symbol(const char *name)
167+static struct symbol *find_symbol(const char *name)
159168 {
160169 struct symbol *s;
161170
@@ -170,25 +179,42 @@ find_symbol(const char *name) · 8 unmodified lines
170179 return NULL;
171180 }
172181
173−/* Add an exported symbol - it may have already been added without a
174− * CRC, in this case just update the CRC */
175−void
176−add_exported_symbol(const char *name, struct module *module, unsigned int *crc)
182+/**
183+ * Add an exported symbol - it may have already been added without a
184+ * CRC, in this case just update the CRC
185+ **/
186+static struct symbol *sym_add_exported(const char *name, struct module *mod)
177187 {
178188 struct symbol *s = find_symbol(name);
179189
180190 if (!s) {
181− new_symbol(name, module, crc);
182− return;
183− }
184− if (crc) {
185− s->crc = *crc;
186− s->crc_valid = 1;
191+ s = new_symbol(name, mod);
192+ } else {
193+ if (!s->preloaded) {
194+ warn("%s: '%s' exported twice. Previous export "
195+ "was in %s%s\n", mod->name, name,
196+ s->module->name,
197+ is_vmlinux(s->module->name) ?"":".ko");
198+ }
187199 }
200+ s->preloaded = 0;
201+ s->vmlinux = is_vmlinux(mod->name);
202+ s->kernel = 0;
203+ return s;
204+}
205+
206+static void sym_update_crc(const char *name, struct module *mod,
207+ unsigned int crc)
208+{
209+ struct symbol *s = find_symbol(name);
210+
211+ if (!s)
212+ s = new_symbol(name, mod);
213+ s->crc = crc;
214+ s->crc_valid = 1;
188215 }
189216
190−void *
191−grab_file(const char *filename, unsigned long *size)
217+void *grab_file(const char *filename, unsigned long *size)
192218 {
193219 struct stat st;
194220 void *map;
@@ -207,13 +233,12 @@ grab_file(const char *filename, unsigned long *size) · 12 unmodified lines
207233 return map;
208234 }
209235
210−/*
211− Return a copy of the next line in a mmap'ed file.
212− spaces in the beginning of the line is trimmed away.
213− Return a pointer to a static buffer.
214−*/
215−char*
216−get_next_line(unsigned long *pos, void *file, unsigned long size)
236+/**
237+ * Return a copy of the next line in a mmap'ed file.
238+ * spaces in the beginning of the line is trimmed away.
239+ * Return a pointer to a static buffer.
240+ **/
241+char* get_next_line(unsigned long *pos, void *file, unsigned long size)
217242 {
218243 static char line[4096];
219244 int skip = 1;
@@ -243,14 +268,12 @@ get_next_line(unsigned long *pos, void *file, unsigned long size) · 23 unmodified lines
243268 return NULL;
244269 }
245270
246−void
247−release_file(void *file, unsigned long size)
271+void release_file(void *file, unsigned long size)
248272 {
249273 munmap(file, size);
250274 }
251275
252−void
253−parse_elf(struct elf_info *info, const char *filename)
276+static void parse_elf(struct elf_info *info, const char *filename)
254277 {
255278 unsigned int i;
256279 Elf_Ehdr *hdr = info->hdr;
@@ -297,14 +320,13 @@ parse_elf(struct elf_info *info, const char *filename) · 40 unmodified lines
297320 continue;
298321
299322 info->symtab_start = (void *)hdr + sechdrs[i].sh_offset;
300− info->symtab_stop = (void *)hdr + sechdrs[i].sh_offset
323+ info->symtab_stop = (void *)hdr + sechdrs[i].sh_offset
301324 + sechdrs[i].sh_size;
302− info->strtab = (void *)hdr +
325+ info->strtab = (void *)hdr +
303326 sechdrs[sechdrs[i].sh_link].sh_offset;
304327 }
305328 if (!info->symtab_start) {
306− fprintf(stderr, "modpost: %s no symtab?\n", filename);
307− abort();
329+ fatal("%s has no symtab?\n", filename);
308330 }
309331 /* Fix endianness in symbols */
310332 for (sym = info->symtab_start; sym < info->symtab_stop; sym++) {
@@ -316,36 +338,31 @@ parse_elf(struct elf_info *info, const char *filename) · 5 unmodified lines
316338 return;
317339
318340 truncated:
319− fprintf(stderr, "modpost: %s is truncated.\n", filename);
320− abort();
341+ fatal("%s is truncated.\n", filename);
321342 }
322343
323−void
324−parse_elf_finish(struct elf_info *info)
344+static void parse_elf_finish(struct elf_info *info)
325345 {
326346 release_file(info->hdr, info->size);
327347 }
328348
329−#define CRC_PFX "__crc_"
330−#define KSYMTAB_PFX "__ksymtab_"
349+#define CRC_PFX MODULE_SYMBOL_PREFIX "__crc_"
350+#define KSYMTAB_PFX MODULE_SYMBOL_PREFIX "__ksymtab_"
331351
332−void
333−handle_modversions(struct module *mod, struct elf_info *info,
334− Elf_Sym *sym, const char *symname)
352+static void handle_modversions(struct module *mod, struct elf_info *info,
353+ Elf_Sym *sym, const char *symname)
335354 {
336355 unsigned int crc;
337356
338357 switch (sym->st_shndx) {
339358 case SHN_COMMON:
340− fprintf(stderr, "*** Warning: \"%s\" [%s] is COMMON symbol\n",
341− symname, mod->name);
359+ warn("\"%s\" [%s] is COMMON symbol\n", symname, mod->name);
342360 break;
343361 case SHN_ABS:
344362 /* CRC'd symbol */
345363 if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) {
346364 crc = (unsigned int) sym->st_value;
347− add_exported_symbol(symname + strlen(CRC_PFX),
348− mod, &crc);
365+ sym_update_crc(symname + strlen(CRC_PFX), mod, crc);
349366 }
350367 break;
351368 case SHN_UNDEF:
@@ -370,15 +387,15 @@ handle_modversions(struct module *mod, struct elf_info *info, · 18 unmodified lines
370387 /* Ignore register directives. */
371388 if (ELF_ST_TYPE(sym->st_info) == STT_SPARC_REGISTER)
372389 break;
373− if (symname[0] == '.') {
374− char *munged = strdup(symname);
375− munged[0] = '_';
376− munged[1] = toupper(munged[1]);
377− symname = munged;
378− }
390+ if (symname[0] == '.') {
391+ char *munged = strdup(symname);
392+ munged[0] = '_';
393+ munged[1] = toupper(munged[1]);
394+ symname = munged;
395+ }
379396 }
380397 #endif
381−
398+
382399 if (memcmp(symname, MODULE_SYMBOL_PREFIX,
383400 strlen(MODULE_SYMBOL_PREFIX)) == 0)
384401 mod->unres = alloc_symbol(symname +
@@ -389,8 +406,7 @@ handle_modversions(struct module *mod, struct elf_info *info, · 4 unmodified lines
389406 default:
390407 /* All exported symbols */
391408 if (memcmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) {
392− add_exported_symbol(symname + strlen(KSYMTAB_PFX),
393− mod, NULL);
409+ sym_add_exported(symname + strlen(KSYMTAB_PFX), mod);
394410 }
395411 if (strcmp(symname, MODULE_SYMBOL_PREFIX "init_module") == 0)
396412 mod->has_init = 1;
@@ -400,20 +416,9 @@ handle_modversions(struct module *mod, struct elf_info *info, · 3 unmodified lines
400416 }
401417 }
402418
403−int
404−is_vmlinux(const char *modname)
405−{
406− const char *myname;
407−
408− if ((myname = strrchr(modname, '/')))
409− myname++;
410− else
411− myname = modname;
412−
413− return strcmp(myname, "vmlinux") == 0;
414−}
415−
416−/* Parse tag=value strings from .modinfo section */
419+/**
420+ * Parse tag=value strings from .modinfo section
421+ **/
417422 static char *next_string(char *string, unsigned long *secsize)
418423 {
419424 /* Skip non-zero chars */
@@ -446,8 +451,418 @@ static char *get_modinfo(void *modinfo, unsigned long modinfo_len, · 26 unmodified lines
446451 return NULL;
447452 }
448453
449−void
450−read_symbols(char *modname)
454+/**
455+ * Test if string s ends in string sub
456+ * return 0 if match
457+ **/
458+static int strrcmp(const char *s, const char *sub)
459+{
460+ int slen, sublen;
461+
462+ if (!s || !sub)
463+ return 1;
464+
465+ slen = strlen(s);
466+ sublen = strlen(sub);
467+
468+ if ((slen == 0) || (sublen == 0))
469+ return 1;
470+
471+ if (sublen > slen)
472+ return 1;
473+
474+ return memcmp(s + slen - sublen, sub, sublen);
475+}
476+
477+/**
478+ * Whitelist to allow certain references to pass with no warning.
479+ * Pattern 1:
480+ * If a module parameter is declared __initdata and permissions=0
481+ * then this is legal despite the warning generated.
482+ * We cannot see value of permissions here, so just ignore
483+ * this pattern.
484+ * The pattern is identified by:
485+ * tosec = .init.data
486+ * fromsec = .data*
487+ * atsym =__param*
488+ *
489+ * Pattern 2:
490+ * Many drivers utilise a *_driver container with references to
491+ * add, remove, probe functions etc.
492+ * These functions may often be marked __init and we do not want to
493+ * warn here.
494+ * the pattern is identified by:
495+ * tosec = .init.text | .exit.text
496+ * fromsec = .data
497+ * atsym = *_driver, *_ops, *_probe, *probe_one
498+ **/
499+static int secref_whitelist(const char *tosec, const char *fromsec,
500+ const char *atsym)
501+{
502+ int f1 = 1, f2 = 1;
503+ const char **s;
504+ const char *pat2sym[] = {
505+ "_driver",
506+ "_ops",
507+ "_probe",
508+ "_probe_one",
509+ NULL
510+ };
511+
512+ /* Check for pattern 1 */
513+ if (strcmp(tosec, ".init.data") != 0)
514+ f1 = 0;
515+ if (strncmp(fromsec, ".data", strlen(".data")) != 0)
516+ f1 = 0;
517+ if (strncmp(atsym, "__param", strlen("__param")) != 0)
518+ f1 = 0;
519+
520+ if (f1)
521+ return f1;
522+
523+ /* Check for pattern 2 */
524+ if ((strcmp(tosec, ".init.text") != 0) &&
525+ (strcmp(tosec, ".exit.text") != 0))
526+ f2 = 0;
527+ if (strcmp(fromsec, ".data") != 0)
528+ f2 = 0;
529+
530+ for (s = pat2sym; *s; s++)
531+ if (strrcmp(atsym, *s) == 0)
532+ f1 = 1;
533+
534+ return f1 && f2;
535+}
536+
537+/**
538+ * Find symbol based on relocation record info.
539+ * In some cases the symbol supplied is a valid symbol so
540+ * return refsym. If st_name != 0 we assume this is a valid symbol.
541+ * In other cases the symbol needs to be looked up in the symbol table
542+ * based on section and address.
543+ * **/
544+static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf_Addr addr,
545+ Elf_Sym *relsym)
546+{
547+ Elf_Sym *sym;
548+
549+ if (relsym->st_name != 0)
550+ return relsym;
551+ for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
552+ if (sym->st_shndx != relsym->st_shndx)
553+ continue;
554+ if (sym->st_value == addr)
555+ return sym;
556+ }
557+ return NULL;
558+}
559+
560+/*
561+ * Find symbols before or equal addr and after addr - in the section sec.
562+ * If we find two symbols with equal offset prefer one with a valid name.
563+ * The ELF format may have a better way to detect what type of symbol
564+ * it is, but this works for now.
565+ **/
566+static void find_symbols_between(struct elf_info *elf, Elf_Addr addr,
567+ const char *sec,
568+ Elf_Sym **before, Elf_Sym **after)
569+{
570+ Elf_Sym *sym;
571+ Elf_Ehdr *hdr = elf->hdr;
572+ Elf_Addr beforediff = ~0;
573+ Elf_Addr afterdiff = ~0;
574+ const char *secstrings = (void *)hdr +
575+ elf->sechdrs[hdr->e_shstrndx].sh_offset;
576+
577+ *before = NULL;
578+ *after = NULL;
579+
580+ for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
581+ const char *symsec;
582+
583+ if (sym->st_shndx >= SHN_LORESERVE)
584+ continue;
585+ symsec = secstrings + elf->sechdrs[sym->st_shndx].sh_name;
586+ if (strcmp(symsec, sec) != 0)
587+ continue;
588+ if (sym->st_value <= addr) {
589+ if ((addr - sym->st_value) < beforediff) {
590+ beforediff = addr - sym->st_value;
591+ *before = sym;
592+ }
593+ else if ((addr - sym->st_value) == beforediff) {
594+ /* equal offset, valid name? */
595+ const char *name = elf->strtab + sym->st_name;
596+ if (name && strlen(name))
597+ *before = sym;
598+ }
599+ }
600+ else
601+ {
602+ if ((sym->st_value - addr) < afterdiff) {
603+ afterdiff = sym->st_value - addr;
604+ *after = sym;
605+ }
606+ else if ((sym->st_value - addr) == afterdiff) {
607+ /* equal offset, valid name? */
608+ const char *name = elf->strtab + sym->st_name;
609+ if (name && strlen(name))
610+ *after = sym;
611+ }
612+ }
613+ }
614+}
615+
616+/**
617+ * Print a warning about a section mismatch.
618+ * Try to find symbols near it so user can find it.
619+ * Check whitelist before warning - it may be a false positive.
620+ **/
621+static void warn_sec_mismatch(const char *modname, const char *fromsec,
622+ struct elf_info *elf, Elf_Sym *sym, Elf_Rela r)
623+{
624+ const char *refsymname = "";
625+ Elf_Sym *before, *after;
626+ Elf_Sym *refsym;
627+ Elf_Ehdr *hdr = elf->hdr;
628+ Elf_Shdr *sechdrs = elf->sechdrs;
629+ const char *secstrings = (void *)hdr +
630+ sechdrs[hdr->e_shstrndx].sh_offset;
631+ const char *secname = secstrings + sechdrs[sym->st_shndx].sh_name;
632+
633+ find_symbols_between(elf, r.r_offset, fromsec, &before, &after);
634+
635+ refsym = find_elf_symbol(elf, r.r_addend, sym);
636+ if (refsym && strlen(elf->strtab + refsym->st_name))
637+ refsymname = elf->strtab + refsym->st_name;
638+
639+ /* check whitelist - we may ignore it */
640+ if (before &&
641+ secref_whitelist(secname, fromsec, elf->strtab + before->st_name))
642+ return;
643+
644+ if (before && after) {
645+ warn("%s - Section mismatch: reference to %s:%s from %s "
646+ "between '%s' (at offset 0x%llx) and '%s'\n",
647+ modname, secname, refsymname, fromsec,
648+ elf->strtab + before->st_name,
649+ (long long)r.r_offset,
650+ elf->strtab + after->st_name);
651+ } else if (before) {
652+ warn("%s - Section mismatch: reference to %s:%s from %s "
653+ "after '%s' (at offset 0x%llx)\n",
654+ modname, secname, refsymname, fromsec,
655+ elf->strtab + before->st_name,
656+ (long long)r.r_offset);
657+ } else if (after) {
658+ warn("%s - Section mismatch: reference to %s:%s from %s "
659+ "before '%s' (at offset -0x%llx)\n",
660+ modname, secname, refsymname, fromsec,
661+ elf->strtab + before->st_name,
662+ (long long)r.r_offset);
663+ } else {
664+ warn("%s - Section mismatch: reference to %s:%s from %s "
665+ "(offset 0x%llx)\n",
666+ modname, secname, fromsec, refsymname,
667+ (long long)r.r_offset);
668+ }
669+}
670+
671+/**
672+ * A module includes a number of sections that are discarded
673+ * either when loaded or when used as built-in.
674+ * For loaded modules all functions marked __init and all data
675+ * marked __initdata will be discarded when the module has been intialized.
676+ * Likewise for modules used built-in the sections marked __exit
677+ * are discarded because __exit marked function are supposed to be called
678+ * only when a moduel is unloaded which never happes for built-in modules.
679+ * The check_sec_ref() function traverses all relocation records
680+ * to find all references to a section that reference a section that will
681+ * be discarded and warns about it.
682+ **/
683+static void check_sec_ref(struct module *mod, const char *modname,
684+ struct elf_info *elf,
685+ int section(const char*),
686+ int section_ref_ok(const char *))
687+{
688+ int i;
689+ Elf_Sym *sym;
690+ Elf_Ehdr *hdr = elf->hdr;
691+ Elf_Shdr *sechdrs = elf->sechdrs;
692+ const char *secstrings = (void *)hdr +
693+ sechdrs[hdr->e_shstrndx].sh_offset;
694+
695+ /* Walk through all sections */
696+ for (i = 0; i < hdr->e_shnum; i++) {
697+ Elf_Rela *rela;
698+ Elf_Rela *start = (void *)hdr + sechdrs[i].sh_offset;
699+ Elf_Rela *stop = (void*)start + sechdrs[i].sh_size;
700+ const char *name = secstrings + sechdrs[i].sh_name +
701+ strlen(".rela");
702+ /* We want to process only relocation sections and not .init */
703+ if (section_ref_ok(name) || (sechdrs[i].sh_type != SHT_RELA))
704+ continue;
705+
706+ for (rela = start; rela < stop; rela++) {
707+ Elf_Rela r;
708+ const char *secname;
709+ r.r_offset = TO_NATIVE(rela->r_offset);
710+ r.r_info = TO_NATIVE(rela->r_info);
711+ r.r_addend = TO_NATIVE(rela->r_addend);
712+ sym = elf->symtab_start + ELF_R_SYM(r.r_info);
713+ /* Skip special sections */
714+ if (sym->st_shndx >= SHN_LORESERVE)
715+ continue;
716+
717+ secname = secstrings + sechdrs[sym->st_shndx].sh_name;
718+ if (section(secname))
719+ warn_sec_mismatch(modname, name, elf, sym, r);
720+ }
721+ }
722+}
723+
724+/**
725+ * Functions used only during module init is marked __init and is stored in
726+ * a .init.text section. Likewise data is marked __initdata and stored in
727+ * a .init.data section.
728+ * If this section is one of these sections return 1
729+ * See include/linux/init.h for the details
730+ **/
731+static int init_section(const char *name)
732+{
733+ if (strcmp(name, ".init") == 0)
734+ return 1;
735+ if (strncmp(name, ".init.", strlen(".init.")) == 0)
736+ return 1;
737+ return 0;
738+}
739+
740+/**
741+ * Identify sections from which references to a .init section is OK.
742+ *
743+ * Unfortunately references to read only data that referenced .init
744+ * sections had to be excluded. Almost all of these are false
745+ * positives, they are created by gcc. The downside of excluding rodata
746+ * is that there really are some user references from rodata to
747+ * init code, e.g. drivers/video/vgacon.c:
748+ *
749+ * const struct consw vga_con = {
750+ * con_startup: vgacon_startup,
751+ *
752+ * where vgacon_startup is __init. If you want to wade through the false
753+ * positives, take out the check for rodata.
754+ **/
755+static int init_section_ref_ok(const char *name)
756+{
757+ const char **s;
758+ /* Absolute section names */
759+ const char *namelist1[] = {
760+ ".init",
761+ ".opd", /* see comment [OPD] at exit_section_ref_ok() */
762+ ".toc1", /* used by ppc64 */
763+ ".stab",
764+ ".rodata",
765+ ".text.lock",
766+ "__bug_table", /* used by powerpc for BUG() */
767+ ".pci_fixup_header",
768+ ".pci_fixup_final",
769+ ".pdr",
770+ "__param",
771+ NULL
772+ };
773+ /* Start of section names */
774+ const char *namelist2[] = {
775+ ".init.",
776+ ".altinstructions",
777+ ".eh_frame",
778+ ".debug",
779+ NULL
780+ };
781+ /* part of section name */
782+ const char *namelist3 [] = {
783+ ".unwind", /* sample: IA_64.unwind.init.text */
784+ NULL
785+ };
786+
787+ for (s = namelist1; *s; s++)
788+ if (strcmp(*s, name) == 0)
789+ return 1;
790+ for (s = namelist2; *s; s++)
791+ if (strncmp(*s, name, strlen(*s)) == 0)
792+ return 1;
793+ for (s = namelist3; *s; s++)
794+ if (strstr(name, *s) != NULL)
795+ return 1;
796+ return 0;
797+}
798+
799+/*
800+ * Functions used only during module exit is marked __exit and is stored in
801+ * a .exit.text section. Likewise data is marked __exitdata and stored in
802+ * a .exit.data section.
803+ * If this section is one of these sections return 1
804+ * See include/linux/init.h for the details
805+ **/
806+static int exit_section(const char *name)
807+{
808+ if (strcmp(name, ".exit.text") == 0)
809+ return 1;
810+ if (strcmp(name, ".exit.data") == 0)
811+ return 1;
812+ return 0;
813+
814+}
815+
816+/*
817+ * Identify sections from which references to a .exit section is OK.
818+ *
819+ * [OPD] Keith Ownes <kaos@sgi.com> commented:
820+ * For our future {in}sanity, add a comment that this is the ppc .opd
821+ * section, not the ia64 .opd section.
822+ * ia64 .opd should not point to discarded sections.
823+ **/
824+static int exit_section_ref_ok(const char *name)
825+{
826+ const char **s;
827+ /* Absolute section names */
828+ const char *namelist1[] = {
829+ ".exit.text",
830+ ".exit.data",
831+ ".init.text",
832+ ".opd", /* See comment [OPD] */
833+ ".toc1", /* used by ppc64 */
834+ ".altinstructions",
835+ ".pdr",
836+ "__bug_table", /* used by powerpc for BUG() */
837+ ".exitcall.exit",
838+ ".eh_frame",
839+ ".stab",
840+ NULL
841+ };
842+ /* Start of section names */
843+ const char *namelist2[] = {
844+ ".debug",
845+ NULL
846+ };
847+ /* part of section name */
848+ const char *namelist3 [] = {
849+ ".unwind", /* Sample: IA_64.unwind.exit.text */
850+ NULL
851+ };
852+
853+ for (s = namelist1; *s; s++)
854+ if (strcmp(*s, name) == 0)
855+ return 1;
856+ for (s = namelist2; *s; s++)
857+ if (strncmp(*s, name, strlen(*s)) == 0)
858+ return 1;
859+ for (s = namelist3; *s; s++)
860+ if (strstr(name, *s) != NULL)
861+ return 1;
862+ return 0;
863+}
864+
865+static void read_symbols(char *modname)
451866 {
452867 const char *symname;
453868 char *version;
@@ -462,9 +877,7 @@ read_symbols(char *modname) · 8 unmodified lines
462877 /* When there's no vmlinux, don't print warnings about
463878 * unresolved symbols (since there'll be too many ;) */
464879 if (is_vmlinux(modname)) {
465− unsigned int fake_crc = 0;
466880 have_vmlinux = 1;
467− add_exported_symbol("struct_module", mod, &fake_crc);
468881 mod->skip = 1;
469882 }
470883
@@ -474,6 +887,8 @@ read_symbols(char *modname) · 3 unmodified lines
474887 handle_modversions(mod, &info, sym, symname);
475888 handle_moddevtable(mod, &info, sym, symname);
476889 }
890+ check_sec_ref(mod, modname, &info, init_section, init_section_ref_ok);
891+ check_sec_ref(mod, modname, &info, exit_section, exit_section_ref_ok);
477892
478893 version = get_modinfo(info.modinfo, info.modinfo_len, "version");
479894 if (version)
@@ -499,21 +914,20 @@ read_symbols(char *modname) · 19 unmodified lines
499914 * following helper, then compare to the file on disk and
500915 * only update the later if anything changed */
501916
502−void __attribute__((format(printf, 2, 3)))
503−buf_printf(struct buffer *buf, const char *fmt, ...)
917+void __attribute__((format(printf, 2, 3))) buf_printf(struct buffer *buf,
918+ const char *fmt, ...)
504919 {
505920 char tmp[SZ];
506921 int len;
507922 va_list ap;
508−
923+
509924 va_start(ap, fmt);
510925 len = vsnprintf(tmp, SZ, fmt, ap);
511926 buf_write(buf, tmp, len);
512927 va_end(ap);
513928 }
514929
515−void
516−buf_write(struct buffer *buf, const char *s, int len)
930+void buf_write(struct buffer *buf, const char *s, int len)
517931 {
518932 if (buf->size - buf->pos < len) {
519933 buf->size += len + SZ;
@@ -523,10 +937,10 @@ buf_write(struct buffer *buf, const char *s, int len) · 3 unmodified lines
523937 buf->pos += len;
524938 }
525939
526−/* Header for the generated file */
527−
528−void
529−add_header(struct buffer *b, struct module *mod)
940+/**
941+ * Header for the generated file
942+ **/
943+static void add_header(struct buffer *b, struct module *mod)
530944 {
531945 buf_printf(b, "#include <linux/module.h>\n");
532946 buf_printf(b, "#include <linux/vermagic.h>\n");
@@ -546,10 +960,10 @@ add_header(struct buffer *b, struct module *mod) · 13 unmodified lines
546960 buf_printf(b, "};\n");
547961 }
548962
549−/* Record CRCs for unresolved symbols */
550−
551−void
552−add_versions(struct buffer *b, struct module *mod)
963+/**
964+ * Record CRCs for unresolved symbols
965+ **/
966+static void add_versions(struct buffer *b, struct module *mod)
553967 {
554968 struct symbol *s, *exp;
555969
@@ -557,8 +971,8 @@ add_versions(struct buffer *b, struct module *mod) · 1 unmodified line
557971 exp = find_symbol(s->name);
558972 if (!exp || exp->module == mod) {
559973 if (have_vmlinux && !s->weak)
560− fprintf(stderr, "*** Warning: \"%s\" [%s.ko] "
561− "undefined!\n", s->name, mod->name);
974+ warn("\"%s\" [%s.ko] undefined!\n",
975+ s->name, mod->name);
562976 continue;
563977 }
564978 s->module = exp->module;
@@ -579,8 +993,7 @@ add_versions(struct buffer *b, struct module *mod) · 14 unmodified lines
579993 continue;
580994 }
581995 if (!s->crc_valid) {
582− fprintf(stderr, "*** Warning: \"%s\" [%s.ko] "
583− "has no CRC!\n",
996+ warn("\"%s\" [%s.ko] has no CRC!\n",
584997 s->name, mod->name);
585998 continue;
586999 }
@@ -590,8 +1003,8 @@ add_versions(struct buffer *b, struct module *mod) · 3 unmodified lines
5901003 buf_printf(b, "};\n");
5911004 }
5921005
593−void
594−add_depends(struct buffer *b, struct module *mod, struct module *modules)
1006+static void add_depends(struct buffer *b, struct module *mod,
1007+ struct module *modules)
5951008 {
5961009 struct symbol *s;
5971010 struct module *m;
@@ -621,8 +1034,7 @@ add_depends(struct buffer *b, struct module *mod, struct module *modules) · 23 unmodified lines
6211034 buf_printf(b, "\";\n");
6221035 }
6231036
624−void
625−add_srcversion(struct buffer *b, struct module *mod)
1037+static void add_srcversion(struct buffer *b, struct module *mod)
6261038 {
6271039 if (mod->srcversion[0]) {
6281040 buf_printf(b, "\n");
@@ -631,8 +1043,7 @@ add_srcversion(struct buffer *b, struct module *mod) · 2 unmodified lines
6311043 }
6321044 }
6331045
634−void
635−write_if_changed(struct buffer *b, const char *fname)
1046+static void write_if_changed(struct buffer *b, const char *fname)
6361047 {
6371048 char *tmp;
6381049 FILE *file;
@@ -676,8 +1087,7 @@ write_if_changed(struct buffer *b, const char *fname) · 37 unmodified lines
6761087 fclose(file);
6771088 }
6781089
679−void
680−read_dump(const char *fname)
1090+static void read_dump(const char *fname, unsigned int kernel)
6811091 {
6821092 unsigned long size, pos = 0;
6831093 void *file = grab_file(fname, &size);
@@ -691,6 +1101,7 @@ read_dump(const char *fname) · 7 unmodified lines
6911101 char *symname, *modname, *d;
6921102 unsigned int crc;
6931103 struct module *mod;
1104+ struct symbol *s;
6941105
6951106 if (!(symname = strchr(line, '\t')))
6961107 goto fail;
@@ -711,15 +1122,30 @@ read_dump(const char *fname) · 14 unmodified lines
7111122 mod = new_module(NOFAIL(strdup(modname)));
7121123 mod->skip = 1;
7131124 }
714− add_exported_symbol(symname, mod, &crc);
1125+ s = sym_add_exported(symname, mod);
1126+ s->kernel = kernel;
1127+ s->preloaded = 1;
1128+ sym_update_crc(symname, mod, crc);
7151129 }
7161130 return;
7171131 fail:
7181132 fatal("parse error in symbol dump file\n");
7191133 }
7201134
721−void
722−write_dump(const char *fname)
1135+/* For normal builds always dump all symbols.
1136+ * For external modules only dump symbols
1137+ * that are not read from kernel Module.symvers.
1138+ **/
1139+static int dump_sym(struct symbol *sym)
1140+{
1141+ if (!external_module)
1142+ return 1;
1143+ if (sym->vmlinux || sym->kernel)
1144+ return 0;
1145+ return 1;
1146+}
1147+
1148+static void write_dump(const char *fname)
7231149 {
7241150 struct buffer buf = { };
7251151 struct symbol *symbol;
@@ -728,34 +1154,33 @@ write_dump(const char *fname) · 2 unmodified lines
7281154 for (n = 0; n < SYMBOL_HASH_SIZE ; n++) {
7291155 symbol = symbolhash[n];
7301156 while (symbol) {
731− symbol = symbol->next;
732− }
733− }
734−
735− for (n = 0; n < SYMBOL_HASH_SIZE ; n++) {
736− symbol = symbolhash[n];
737− while (symbol) {
738− buf_printf(&buf, "0x%08x\t%s\t%s\n", symbol->crc,
739− symbol->name, symbol->module->name);
1157+ if (dump_sym(symbol))
1158+ buf_printf(&buf, "0x%08x\t%s\t%s\n",
1159+ symbol->crc, symbol->name,
1160+ symbol->module->name);
7401161 symbol = symbol->next;
7411162 }
7421163 }
7431164 write_if_changed(&buf, fname);
7441165 }
7451166
746−int
747−main(int argc, char **argv)
1167+int main(int argc, char **argv)
7481168 {
7491169 struct module *mod;
7501170 struct buffer buf = { };
7511171 char fname[SZ];
752− char *dump_read = NULL, *dump_write = NULL;
1172+ char *kernel_read = NULL, *module_read = NULL;
1173+ char *dump_write = NULL;
7531174 int opt;
7541175
755− while ((opt = getopt(argc, argv, "i:mo:a")) != -1) {
1176+ while ((opt = getopt(argc, argv, "i:I:mo:a")) != -1) {
7561177 switch(opt) {
7571178 case 'i':
758− dump_read = optarg;
1179+ kernel_read = optarg;
1180+ break;
1181+ case 'I':
1182+ module_read = optarg;
1183+ external_module = 1;
7591184 break;
7601185 case 'm':
7611186 modversions = 1;
@@ -771,8 +1196,10 @@ main(int argc, char **argv) · 9 unmodified lines
7711196 }
7721197 }
7731198
774− if (dump_read)
775− read_dump(dump_read);
1199+ if (kernel_read)
1200+ read_dump(kernel_read, 1);
1201+ if (module_read)
1202+ read_dump(module_read, 0);
7761203
7771204 while (optind < argc) {
7781205 read_symbols(argv[optind++]);
@@ -799,4 +1226,3 @@ main(int argc, char **argv) · 20 unmodified lines
7991226
8001227 return 0;
8011228 }
802−
scripts/mod/modpost.h+20−5
@@ -13,20 +13,30 @@ · 12 unmodified lines
1313
1414 #if KERNEL_ELFCLASS == ELFCLASS32
1515
16−#define Elf_Ehdr Elf32_Ehdr
17−#define Elf_Shdr Elf32_Shdr
16+#define Elf_Ehdr Elf32_Ehdr
17+#define Elf_Shdr Elf32_Shdr
1818 #define Elf_Sym Elf32_Sym
19+#define Elf_Addr Elf32_Addr
20+#define Elf_Section Elf32_Section
1921 #define ELF_ST_BIND ELF32_ST_BIND
2022 #define ELF_ST_TYPE ELF32_ST_TYPE
2123
24+#define Elf_Rela Elf32_Rela
25+#define ELF_R_SYM ELF32_R_SYM
26+#define ELF_R_TYPE ELF32_R_TYPE
2227 #else
2328
24−#define Elf_Ehdr Elf64_Ehdr
25−#define Elf_Shdr Elf64_Shdr
29+#define Elf_Ehdr Elf64_Ehdr
30+#define Elf_Shdr Elf64_Shdr
2631 #define Elf_Sym Elf64_Sym
32+#define Elf_Addr Elf64_Addr
33+#define Elf_Section Elf64_Section
2734 #define ELF_ST_BIND ELF64_ST_BIND
2835 #define ELF_ST_TYPE ELF64_ST_TYPE
2936
37+#define Elf_Rela Elf64_Rela
38+#define ELF_R_SYM ELF64_R_SYM
39+#define ELF_R_TYPE ELF64_R_TYPE
3040 #endif
3141
3242 #if KERNEL_ELFDATA != HOST_ELFDATA
@@ -91,17 +101,22 @@ struct elf_info { · 58 unmodified lines
91101 unsigned int modinfo_len;
92102 };
93103
104+/* file2alias.c */
94105 void handle_moddevtable(struct module *mod, struct elf_info *info,
95106 Elf_Sym *sym, const char *symname);
96−
97107 void add_moddevtable(struct buffer *buf, struct module *mod);
98108
109+/* sumversion.c */
99110 void maybe_frob_rcs_version(const char *modfilename,
100111 char *version,
101112 void *modinfo,
102113 unsigned long modinfo_offset);
103114 void get_src_version(const char *modname, char sum[], unsigned sumlen);
104115
116+/* from modpost.c */
105117 void *grab_file(const char *filename, unsigned long *size);
106118 char* get_next_line(unsigned long *pos, void *file, unsigned long size);
107119 void release_file(void *file, unsigned long size);
120+
121+void fatal(const char *fmt, ...);
122+void warn(const char *fmt, ...);
scripts/mod/sumversion.c+15−17
@@ -316,8 +316,7 @@ static int parse_source_files(const char *objfile, struct md4_ctx *md) · 315 unmodified lines
316316
317317 file = grab_file(cmd, &flen);
318318 if (!file) {
319− fprintf(stderr, "Warning: could not find %s for %s\n",
320− cmd, objfile);
319+ warn("could not find %s for %s\n", cmd, objfile);
321320 goto out;
322321 }
323322
@@ -355,9 +354,8 @@ static int parse_source_files(const char *objfile, struct md4_ctx *md) · 31 unmodified lines
355354 /* Check if this file is in same dir as objfile */
356355 if ((strstr(line, dir)+strlen(dir)-1) == strrchr(line, '/')) {
357356 if (!parse_file(line, md)) {
358− fprintf(stderr,
359− "Warning: could not open %s: %s\n",
360− line, strerror(errno));
357+ warn("could not open %s: %s\n",
358+ line, strerror(errno));
361359 goto out_file;
362360 }
363361
@@ -383,8 +381,11 @@ void get_src_version(const char *modname, char sum[], unsigned sumlen) · 19 unmodified lines
383381 struct md4_ctx md;
384382 char *sources, *end, *fname;
385383 const char *basename;
386− char filelist[strlen(getenv("MODVERDIR")) + strlen("/") +
387− strlen(modname) - strlen(".o") + strlen(".mod") + 1 ];
384+ char filelist[PATH_MAX + 1];
385+ char *modverdir = getenv("MODVERDIR");
386+
387+ if (!modverdir)
388+ modverdir = ".";
388389
389390 /* Source files for module are in .tmp_versions/modname.mod,
390391 after the first line. */
@@ -392,28 +393,25 @@ void get_src_version(const char *modname, char sum[], unsigned sumlen) · 1 unmodified line
392393 basename = strrchr(modname, '/') + 1;
393394 else
394395 basename = modname;
395− sprintf(filelist, "%s/%.*s.mod", getenv("MODVERDIR"),
396+ sprintf(filelist, "%s/%.*s.mod", modverdir,
396397 (int) strlen(basename) - 2, basename);
397398
398399 file = grab_file(filelist, &len);
399400 if (!file) {
400− fprintf(stderr, "Warning: could not find versions for %s\n",
401− filelist);
401+ warn("could not find versions for %s\n", filelist);
402402 return;
403403 }
404404
405405 sources = strchr(file, '\n');
406406 if (!sources) {
407− fprintf(stderr, "Warning: malformed versions file for %s\n",
408− modname);
407+ warn("malformed versions file for %s\n", modname);
409408 goto release;
410409 }
411410
412411 sources++;
413412 end = strchr(sources, '\n');
414413 if (!end) {
415− fprintf(stderr, "Warning: bad ending versions file for %s\n",
416− modname);
414+ warn("bad ending versions file for %s\n", modname);
417415 goto release;
418416 }
419417 *end = '\0';
@@ -438,19 +436,19 @@ static void write_version(const char *filename, const char *sum, · 18 unmodified lines
438436
439437 fd = open(filename, O_RDWR);
440438 if (fd < 0) {
441− fprintf(stderr, "Warning: changing sum in %s failed: %s\n",
439+ warn("changing sum in %s failed: %s\n",
442440 filename, strerror(errno));
443441 return;
444442 }
445443
446444 if (lseek(fd, offset, SEEK_SET) == (off_t)-1) {
447− fprintf(stderr, "Warning: changing sum in %s:%lu failed: %s\n",
445+ warn("changing sum in %s:%lu failed: %s\n",
448446 filename, offset, strerror(errno));
449447 goto out;
450448 }
451449
452450 if (write(fd, sum, strlen(sum)+1) != strlen(sum)+1) {
453− fprintf(stderr, "Warning: writing sum in %s failed: %s\n",
451+ warn("writing sum in %s failed: %s\n",
454452 filename, strerror(errno));
455453 goto out;
456454 }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t