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
34typedef unsigned char __u8;34typedef unsigned char __u8;
35 35
36/* Big exception to the "don't include kernel headers into userspace, which36/* 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
38 * we handle those differences explicitly below */38 * we handle those differences explicitly below */
39#include "../../include/linux/mod_devicetable.h"39#include "../../include/linux/mod_devicetable.h"
40#include "../../include/linux/input.h"40#include "../../include/linux/input.h"
@@ -153,8 +153,8 @@ static void do_usb_table(void *symval, unsigned long size, · 112 unmodified lines
153 const unsigned long id_size = sizeof(struct usb_device_id);153 const unsigned long id_size = sizeof(struct usb_device_id);
154 154
155 if (size % id_size || size < id_size) {155 if (size % id_size || size < id_size) {
156 fprintf(stderr, "*** Warning: %s ids %lu bad size "156 warn("%s ids %lu bad size "
157 "(each on %lu)\n", mod->name, size, id_size);157 "(each on %lu)\n", mod->name, size, id_size);
158 }158 }
159 /* Leave last one: it's the terminator. */159 /* Leave last one: it's the terminator. */
160 size -= id_size;160 size -= id_size;
@@ -217,9 +217,8 @@ static int do_pci_entry(const char *filename, · 56 unmodified lines
217 if ((baseclass_mask != 0 && baseclass_mask != 0xFF)217 if ((baseclass_mask != 0 && baseclass_mask != 0xFF)
218 || (subclass_mask != 0 && subclass_mask != 0xFF)218 || (subclass_mask != 0 && subclass_mask != 0xFF)
219 || (interface_mask != 0 && interface_mask != 0xFF)) {219 || (interface_mask != 0 && interface_mask != 0xFF)) {
220 fprintf(stderr,220 warn("Can't handle masks in %s:%04X\n",
221 "*** Warning: Can't handle masks in %s:%04X\n",221 filename, id->class_mask);
222 filename, id->class_mask);
223 return 0;222 return 0;
224 }223 }
225 224
@@ -229,7 +228,7 @@ static int do_pci_entry(const char *filename, · 3 unmodified lines
229 return 1;228 return 1;
230}229}
231 230
232/* looks like: "ccw:tNmNdtNdmN" */ 231/* looks like: "ccw:tNmNdtNdmN" */
233static int do_ccw_entry(const char *filename,232static int do_ccw_entry(const char *filename,
234 struct ccw_device_id *id, char *alias)233 struct ccw_device_id *id, char *alias)
235{234{
@@ -445,8 +444,8 @@ static void do_table(void *symval, unsigned long size, · 209 unmodified lines
445 int (*do_entry)(const char *, void *entry, char *alias) = function;444 int (*do_entry)(const char *, void *entry, char *alias) = function;
446 445
447 if (size % id_size || size < id_size) {446 if (size % id_size || size < id_size) {
448 fprintf(stderr, "*** Warning: %s ids %lu bad size "447 warn("%s ids %lu bad size "
449 "(each on %lu)\n", mod->name, size, id_size);448 "(each on %lu)\n", mod->name, size, id_size);
450 }449 }
451 /* Leave last one: it's the terminator. */450 /* Leave last one: it's the terminator. */
452 size -= id_size;451 size -= id_size;
scripts/mod/mk_elfconfig.c+2−2
@@ -6,7 +6,7 @@ · 5 unmodified lines
6int6int
7main(int argc, char **argv)7main(int argc, char **argv)
8{8{
9 unsigned char ei[EI_NIDENT]; 9 unsigned char ei[EI_NIDENT];
10 union { short s; char c[2]; } endian_test;10 union { short s; char c[2]; } endian_test;
11 11
12 if (argc != 2) {12 if (argc != 2) {
@@ -57,7 +57,7 @@ main(int argc, char **argv) · 44 unmodified lines
57 57
58 if ((strcmp(argv[1], "v850") == 0) || (strcmp(argv[1], "h8300") == 0))58 if ((strcmp(argv[1], "v850") == 0) || (strcmp(argv[1], "h8300") == 0))
59 printf("#define MODULE_SYMBOL_PREFIX \"_\"\n");59 printf("#define MODULE_SYMBOL_PREFIX \"_\"\n");
60 else 60 else
61 printf("#define MODULE_SYMBOL_PREFIX \"\"\n");61 printf("#define MODULE_SYMBOL_PREFIX \"\"\n");
62 62
63 return 0;63 return 0;
scripts/mod/modpost.c+562−136
@@ -2,7 +2,7 @@ · 1 unmodified line
2 *2 *
3 * Copyright 2003 Kai Germaschewski3 * Copyright 2003 Kai Germaschewski
4 * Copyright 2002-2004 Rusty Russell, IBM Corporation4 * Copyright 2002-2004 Rusty Russell, IBM Corporation
5 *5 * Copyright 2006 Sam Ravnborg
6 * Based in part on module-init-tools/depmod.c,file2alias6 * Based in part on module-init-tools/depmod.c,file2alias
7 *7 *
8 * This software may be used and distributed according to the terms8 * This software may be used and distributed according to the terms
@@ -20,9 +20,10 @@ int modversions = 0; · 11 unmodified lines
20int have_vmlinux = 0;20int have_vmlinux = 0;
21/* Is CONFIG_MODULE_SRCVERSION_ALL set? */21/* Is CONFIG_MODULE_SRCVERSION_ALL set? */
22static int all_versions = 0;22static int all_versions = 0;
23/* If we are modposting external module set to 1 */
24static int external_module = 0;
23 25
24void26void fatal(const char *fmt, ...)
25fatal(const char *fmt, ...)
26{27{
27 va_list arglist;28 va_list arglist;
28 29
@@ -35,8 +36,7 @@ fatal(const char *fmt, ...) · 6 unmodified lines
35 exit(1);36 exit(1);
36}37}
37 38
38void39void warn(const char *fmt, ...)
39warn(const char *fmt, ...)
40{40{
41 va_list arglist;41 va_list arglist;
42 42
@@ -47,6 +47,18 @@ warn(const char *fmt, ...) · 4 unmodified lines
47 va_end(arglist);47 va_end(arglist);
48}48}
49 49
50static 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
50void *do_nofail(void *ptr, const char *expr)62void *do_nofail(void *ptr, const char *expr)
51{63{
52 if (!ptr) {64 if (!ptr) {
@@ -59,8 +71,7 @@ void *do_nofail(void *ptr, const char *expr) · 6 unmodified lines
59 71
60static struct module *modules;72static struct module *modules;
61 73
62struct module *74static struct module *find_module(char *modname)
63find_module(char *modname)
64{75{
65 struct module *mod;76 struct module *mod;
66 77
@@ -70,12 +81,11 @@ find_module(char *modname) · 3 unmodified lines
70 return mod;81 return mod;
71}82}
72 83
73struct module *84static struct module *new_module(char *modname)
74new_module(char *modname)
75{85{
76 struct module *mod;86 struct module *mod;
77 char *p, *s;87 char *p, *s;
78 88
79 mod = NOFAIL(malloc(sizeof(*mod)));89 mod = NOFAIL(malloc(sizeof(*mod)));
80 memset(mod, 0, sizeof(*mod));90 memset(mod, 0, sizeof(*mod));
81 p = NOFAIL(strdup(modname));91 p = NOFAIL(strdup(modname));
@@ -104,6 +114,10 @@ struct symbol { · 22 unmodified lines
104 unsigned int crc;114 unsigned int crc;
105 int crc_valid;115 int crc_valid;
106 unsigned int weak:1;116 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 */
107 char name[0];121 char name[0];
108};122};
109 123
@@ -122,11 +136,12 @@ static inline unsigned int tdb_hash(const char *name) · 12 unmodified lines
122 return (1103515243 * value + 12345);136 return (1103515243 * value + 12345);
123}137}
124 138
125/* Allocate a new symbols for use in the hash of exported symbols or139/**
126 * the list of unresolved symbols per module */140 * Allocate a new symbols for use in the hash of exported symbols or
127 141 * the list of unresolved symbols per module
128struct symbol *142 **/
129alloc_symbol(const char *name, unsigned int weak, struct symbol *next)143static struct symbol *alloc_symbol(const char *name, unsigned int weak,
144 struct symbol *next)
130{145{
131 struct symbol *s = NOFAIL(malloc(sizeof(*s) + strlen(name) + 1));146 struct symbol *s = NOFAIL(malloc(sizeof(*s) + strlen(name) + 1));
132 147
@@ -138,9 +153,7 @@ alloc_symbol(const char *name, unsigned int weak, struct symbol *next) · 5 unmodified lines
138}153}
139 154
140/* For the hash of exported symbols */155/* For the hash of exported symbols */
141 156static struct symbol *new_symbol(const char *name, struct module *module)
142void
143new_symbol(const char *name, struct module *module, unsigned int *crc)
144{157{
145 unsigned int hash;158 unsigned int hash;
146 struct symbol *new;159 struct symbol *new;
@@ -148,14 +161,10 @@ new_symbol(const char *name, struct module *module, unsigned int *crc) · 1 unmodified line
148 hash = tdb_hash(name) % SYMBOL_HASH_SIZE;161 hash = tdb_hash(name) % SYMBOL_HASH_SIZE;
149 new = symbolhash[hash] = alloc_symbol(name, 0, symbolhash[hash]);162 new = symbolhash[hash] = alloc_symbol(name, 0, symbolhash[hash]);
150 new->module = module;163 new->module = module;
151 if (crc) {164 return new;
152 new->crc = *crc;
153 new->crc_valid = 1;
154 }
155}165}
156 166
157struct symbol *167static struct symbol *find_symbol(const char *name)
158find_symbol(const char *name)
159{168{
160 struct symbol *s;169 struct symbol *s;
161 170
@@ -170,25 +179,42 @@ find_symbol(const char *name) · 8 unmodified lines
170 return NULL;179 return NULL;
171}180}
172 181
173/* Add an exported symbol - it may have already been added without a182/**
174 * CRC, in this case just update the CRC */183 * Add an exported symbol - it may have already been added without a
175void184 * CRC, in this case just update the CRC
176add_exported_symbol(const char *name, struct module *module, unsigned int *crc)185 **/
186static struct symbol *sym_add_exported(const char *name, struct module *mod)
177{187{
178 struct symbol *s = find_symbol(name);188 struct symbol *s = find_symbol(name);
179 189
180 if (!s) {190 if (!s) {
181 new_symbol(name, module, crc);191 s = new_symbol(name, mod);
182 return;192 } else {
183 }193 if (!s->preloaded) {
184 if (crc) {194 warn("%s: '%s' exported twice. Previous export "
185 s->crc = *crc;195 "was in %s%s\n", mod->name, name,
186 s->crc_valid = 1;196 s->module->name,
197 is_vmlinux(s->module->name) ?"":".ko");
198 }
187 }199 }
200 s->preloaded = 0;
201 s->vmlinux = is_vmlinux(mod->name);
202 s->kernel = 0;
203 return s;
204}
205
206static 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;
188}215}
189 216
190void *217void *grab_file(const char *filename, unsigned long *size)
191grab_file(const char *filename, unsigned long *size)
192{218{
193 struct stat st;219 struct stat st;
194 void *map;220 void *map;
@@ -207,13 +233,12 @@ grab_file(const char *filename, unsigned long *size) · 12 unmodified lines
207 return map;233 return map;
208}234}
209 235
210/*236/**
211 Return a copy of the next line in a mmap'ed file.237 * Return a copy of the next line in a mmap'ed file.
212 spaces in the beginning of the line is trimmed away.238 * spaces in the beginning of the line is trimmed away.
213 Return a pointer to a static buffer.239 * Return a pointer to a static buffer.
214*/240 **/
215char*241char* get_next_line(unsigned long *pos, void *file, unsigned long size)
216get_next_line(unsigned long *pos, void *file, unsigned long size)
217{242{
218 static char line[4096];243 static char line[4096];
219 int skip = 1;244 int skip = 1;
@@ -243,14 +268,12 @@ get_next_line(unsigned long *pos, void *file, unsigned long size) · 23 unmodified lines
243 return NULL;268 return NULL;
244}269}
245 270
246void271void release_file(void *file, unsigned long size)
247release_file(void *file, unsigned long size)
248{272{
249 munmap(file, size);273 munmap(file, size);
250}274}
251 275
252void276static void parse_elf(struct elf_info *info, const char *filename)
253parse_elf(struct elf_info *info, const char *filename)
254{277{
255 unsigned int i;278 unsigned int i;
256 Elf_Ehdr *hdr = info->hdr;279 Elf_Ehdr *hdr = info->hdr;
@@ -297,14 +320,13 @@ parse_elf(struct elf_info *info, const char *filename) · 40 unmodified lines
297 continue;320 continue;
298 321
299 info->symtab_start = (void *)hdr + sechdrs[i].sh_offset;322 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
301 + sechdrs[i].sh_size;324 + sechdrs[i].sh_size;
302 info->strtab = (void *)hdr + 325 info->strtab = (void *)hdr +
303 sechdrs[sechdrs[i].sh_link].sh_offset;326 sechdrs[sechdrs[i].sh_link].sh_offset;
304 }327 }
305 if (!info->symtab_start) {328 if (!info->symtab_start) {
306 fprintf(stderr, "modpost: %s no symtab?\n", filename);329 fatal("%s has no symtab?\n", filename);
307 abort();
308 }330 }
309 /* Fix endianness in symbols */331 /* Fix endianness in symbols */
310 for (sym = info->symtab_start; sym < info->symtab_stop; sym++) {332 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
316 return;338 return;
317 339
318 truncated:340 truncated:
319 fprintf(stderr, "modpost: %s is truncated.\n", filename);341 fatal("%s is truncated.\n", filename);
320 abort();
321}342}
322 343
323void344static void parse_elf_finish(struct elf_info *info)
324parse_elf_finish(struct elf_info *info)
325{345{
326 release_file(info->hdr, info->size);346 release_file(info->hdr, info->size);
327}347}
328 348
329#define CRC_PFX "__crc_"349#define CRC_PFX MODULE_SYMBOL_PREFIX "__crc_"
330#define KSYMTAB_PFX "__ksymtab_"350#define KSYMTAB_PFX MODULE_SYMBOL_PREFIX "__ksymtab_"
331 351
332void352static void handle_modversions(struct module *mod, struct elf_info *info,
333handle_modversions(struct module *mod, struct elf_info *info,353 Elf_Sym *sym, const char *symname)
334 Elf_Sym *sym, const char *symname)
335{354{
336 unsigned int crc;355 unsigned int crc;
337 356
338 switch (sym->st_shndx) {357 switch (sym->st_shndx) {
339 case SHN_COMMON:358 case SHN_COMMON:
340 fprintf(stderr, "*** Warning: \"%s\" [%s] is COMMON symbol\n",359 warn("\"%s\" [%s] is COMMON symbol\n", symname, mod->name);
341 symname, mod->name);
342 break;360 break;
343 case SHN_ABS:361 case SHN_ABS:
344 /* CRC'd symbol */362 /* CRC'd symbol */
345 if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) {363 if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) {
346 crc = (unsigned int) sym->st_value;364 crc = (unsigned int) sym->st_value;
347 add_exported_symbol(symname + strlen(CRC_PFX),365 sym_update_crc(symname + strlen(CRC_PFX), mod, crc);
348 mod, &crc);
349 }366 }
350 break;367 break;
351 case SHN_UNDEF:368 case SHN_UNDEF:
@@ -370,15 +387,15 @@ handle_modversions(struct module *mod, struct elf_info *info, · 18 unmodified lines
370 /* Ignore register directives. */387 /* Ignore register directives. */
371 if (ELF_ST_TYPE(sym->st_info) == STT_SPARC_REGISTER)388 if (ELF_ST_TYPE(sym->st_info) == STT_SPARC_REGISTER)
372 break;389 break;
373 if (symname[0] == '.') {390 if (symname[0] == '.') {
374 char *munged = strdup(symname);391 char *munged = strdup(symname);
375 munged[0] = '_';392 munged[0] = '_';
376 munged[1] = toupper(munged[1]);393 munged[1] = toupper(munged[1]);
377 symname = munged;394 symname = munged;
378 }395 }
379 }396 }
380#endif397#endif
381 398
382 if (memcmp(symname, MODULE_SYMBOL_PREFIX,399 if (memcmp(symname, MODULE_SYMBOL_PREFIX,
383 strlen(MODULE_SYMBOL_PREFIX)) == 0)400 strlen(MODULE_SYMBOL_PREFIX)) == 0)
384 mod->unres = alloc_symbol(symname +401 mod->unres = alloc_symbol(symname +
@@ -389,8 +406,7 @@ handle_modversions(struct module *mod, struct elf_info *info, · 4 unmodified lines
389 default:406 default:
390 /* All exported symbols */407 /* All exported symbols */
391 if (memcmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) {408 if (memcmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) {
392 add_exported_symbol(symname + strlen(KSYMTAB_PFX),409 sym_add_exported(symname + strlen(KSYMTAB_PFX), mod);
393 mod, NULL);
394 }410 }
395 if (strcmp(symname, MODULE_SYMBOL_PREFIX "init_module") == 0)411 if (strcmp(symname, MODULE_SYMBOL_PREFIX "init_module") == 0)
396 mod->has_init = 1;412 mod->has_init = 1;
@@ -400,20 +416,9 @@ handle_modversions(struct module *mod, struct elf_info *info, · 3 unmodified lines
400 }416 }
401}417}
402 418
403int419/**
404is_vmlinux(const char *modname)420 * Parse tag=value strings from .modinfo section
405{421 **/
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 */
417static char *next_string(char *string, unsigned long *secsize)422static char *next_string(char *string, unsigned long *secsize)
418{423{
419 /* Skip non-zero chars */424 /* Skip non-zero chars */
@@ -446,8 +451,418 @@ static char *get_modinfo(void *modinfo, unsigned long modinfo_len, · 26 unmodified lines
446 return NULL;451 return NULL;
447}452}
448 453
449void454/**
450read_symbols(char *modname)455 * Test if string s ends in string sub
456 * return 0 if match
457 **/
458static 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 **/
499static 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 * **/
544static 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 **/
566static 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 **/
621static 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 **/
683static 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 **/
731static 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 **/
755static 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 **/
806static 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 **/
824static 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
865static void read_symbols(char *modname)
451{866{
452 const char *symname;867 const char *symname;
453 char *version;868 char *version;
@@ -462,9 +877,7 @@ read_symbols(char *modname) · 8 unmodified lines
462 /* When there's no vmlinux, don't print warnings about877 /* When there's no vmlinux, don't print warnings about
463 * unresolved symbols (since there'll be too many ;) */878 * unresolved symbols (since there'll be too many ;) */
464 if (is_vmlinux(modname)) {879 if (is_vmlinux(modname)) {
465 unsigned int fake_crc = 0;
466 have_vmlinux = 1;880 have_vmlinux = 1;
467 add_exported_symbol("struct_module", mod, &fake_crc);
468 mod->skip = 1;881 mod->skip = 1;
469 }882 }
470 883
@@ -474,6 +887,8 @@ read_symbols(char *modname) · 3 unmodified lines
474 handle_modversions(mod, &info, sym, symname);887 handle_modversions(mod, &info, sym, symname);
475 handle_moddevtable(mod, &info, sym, symname);888 handle_moddevtable(mod, &info, sym, symname);
476 }889 }
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);
477 892
478 version = get_modinfo(info.modinfo, info.modinfo_len, "version");893 version = get_modinfo(info.modinfo, info.modinfo_len, "version");
479 if (version)894 if (version)
@@ -499,21 +914,20 @@ read_symbols(char *modname) · 19 unmodified lines
499 * following helper, then compare to the file on disk and914 * following helper, then compare to the file on disk and
500 * only update the later if anything changed */915 * only update the later if anything changed */
501 916
502void __attribute__((format(printf, 2, 3)))917void __attribute__((format(printf, 2, 3))) buf_printf(struct buffer *buf,
503buf_printf(struct buffer *buf, const char *fmt, ...)918 const char *fmt, ...)
504{919{
505 char tmp[SZ];920 char tmp[SZ];
506 int len;921 int len;
507 va_list ap;922 va_list ap;
508 923
509 va_start(ap, fmt);924 va_start(ap, fmt);
510 len = vsnprintf(tmp, SZ, fmt, ap);925 len = vsnprintf(tmp, SZ, fmt, ap);
511 buf_write(buf, tmp, len);926 buf_write(buf, tmp, len);
512 va_end(ap);927 va_end(ap);
513}928}
514 929
515void930void buf_write(struct buffer *buf, const char *s, int len)
516buf_write(struct buffer *buf, const char *s, int len)
517{931{
518 if (buf->size - buf->pos < len) {932 if (buf->size - buf->pos < len) {
519 buf->size += len + SZ;933 buf->size += len + SZ;
@@ -523,10 +937,10 @@ buf_write(struct buffer *buf, const char *s, int len) · 3 unmodified lines
523 buf->pos += len;937 buf->pos += len;
524}938}
525 939
526/* Header for the generated file */940/**
527 941 * Header for the generated file
528void942 **/
529add_header(struct buffer *b, struct module *mod)943static void add_header(struct buffer *b, struct module *mod)
530{944{
531 buf_printf(b, "#include <linux/module.h>\n");945 buf_printf(b, "#include <linux/module.h>\n");
532 buf_printf(b, "#include <linux/vermagic.h>\n");946 buf_printf(b, "#include <linux/vermagic.h>\n");
@@ -546,10 +960,10 @@ add_header(struct buffer *b, struct module *mod) · 13 unmodified lines
546 buf_printf(b, "};\n");960 buf_printf(b, "};\n");
547}961}
548 962
549/* Record CRCs for unresolved symbols */963/**
550 964 * Record CRCs for unresolved symbols
551void965 **/
552add_versions(struct buffer *b, struct module *mod)966static void add_versions(struct buffer *b, struct module *mod)
553{967{
554 struct symbol *s, *exp;968 struct symbol *s, *exp;
555 969
@@ -557,8 +971,8 @@ add_versions(struct buffer *b, struct module *mod) · 1 unmodified line
557 exp = find_symbol(s->name);971 exp = find_symbol(s->name);
558 if (!exp || exp->module == mod) {972 if (!exp || exp->module == mod) {
559 if (have_vmlinux && !s->weak)973 if (have_vmlinux && !s->weak)
560 fprintf(stderr, "*** Warning: \"%s\" [%s.ko] "974 warn("\"%s\" [%s.ko] undefined!\n",
561 "undefined!\n", s->name, mod->name);975 s->name, mod->name);
562 continue;976 continue;
563 }977 }
564 s->module = exp->module;978 s->module = exp->module;
@@ -579,8 +993,7 @@ add_versions(struct buffer *b, struct module *mod) · 14 unmodified lines
579 continue;993 continue;
580 }994 }
581 if (!s->crc_valid) {995 if (!s->crc_valid) {
582 fprintf(stderr, "*** Warning: \"%s\" [%s.ko] "996 warn("\"%s\" [%s.ko] has no CRC!\n",
583 "has no CRC!\n",
584 s->name, mod->name);997 s->name, mod->name);
585 continue;998 continue;
586 }999 }
@@ -590,8 +1003,8 @@ add_versions(struct buffer *b, struct module *mod) · 3 unmodified lines
590 buf_printf(b, "};\n");1003 buf_printf(b, "};\n");
591}1004}
592 1005
593void1006static void add_depends(struct buffer *b, struct module *mod,
594add_depends(struct buffer *b, struct module *mod, struct module *modules)1007 struct module *modules)
595{1008{
596 struct symbol *s;1009 struct symbol *s;
597 struct module *m;1010 struct module *m;
@@ -621,8 +1034,7 @@ add_depends(struct buffer *b, struct module *mod, struct module *modules) · 23 unmodified lines
621 buf_printf(b, "\";\n");1034 buf_printf(b, "\";\n");
622}1035}
623 1036
624void1037static void add_srcversion(struct buffer *b, struct module *mod)
625add_srcversion(struct buffer *b, struct module *mod)
626{1038{
627 if (mod->srcversion[0]) {1039 if (mod->srcversion[0]) {
628 buf_printf(b, "\n");1040 buf_printf(b, "\n");
@@ -631,8 +1043,7 @@ add_srcversion(struct buffer *b, struct module *mod) · 2 unmodified lines
631 }1043 }
632}1044}
633 1045
634void1046static void write_if_changed(struct buffer *b, const char *fname)
635write_if_changed(struct buffer *b, const char *fname)
636{1047{
637 char *tmp;1048 char *tmp;
638 FILE *file;1049 FILE *file;
@@ -676,8 +1087,7 @@ write_if_changed(struct buffer *b, const char *fname) · 37 unmodified lines
676 fclose(file);1087 fclose(file);
677}1088}
678 1089
679void1090static void read_dump(const char *fname, unsigned int kernel)
680read_dump(const char *fname)
681{1091{
682 unsigned long size, pos = 0;1092 unsigned long size, pos = 0;
683 void *file = grab_file(fname, &size);1093 void *file = grab_file(fname, &size);
@@ -691,6 +1101,7 @@ read_dump(const char *fname) · 7 unmodified lines
691 char *symname, *modname, *d;1101 char *symname, *modname, *d;
692 unsigned int crc;1102 unsigned int crc;
693 struct module *mod;1103 struct module *mod;
1104 struct symbol *s;
694 1105
695 if (!(symname = strchr(line, '\t')))1106 if (!(symname = strchr(line, '\t')))
696 goto fail;1107 goto fail;
@@ -711,15 +1122,30 @@ read_dump(const char *fname) · 14 unmodified lines
711 mod = new_module(NOFAIL(strdup(modname)));1122 mod = new_module(NOFAIL(strdup(modname)));
712 mod->skip = 1;1123 mod->skip = 1;
713 }1124 }
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);
715 }1129 }
716 return;1130 return;
717fail:1131fail:
718 fatal("parse error in symbol dump file\n");1132 fatal("parse error in symbol dump file\n");
719}1133}
720 1134
721void1135/* For normal builds always dump all symbols.
722write_dump(const char *fname)1136 * For external modules only dump symbols
1137 * that are not read from kernel Module.symvers.
1138 **/
1139static 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
1148static void write_dump(const char *fname)
723{1149{
724 struct buffer buf = { };1150 struct buffer buf = { };
725 struct symbol *symbol;1151 struct symbol *symbol;
@@ -728,34 +1154,33 @@ write_dump(const char *fname) · 2 unmodified lines
728 for (n = 0; n < SYMBOL_HASH_SIZE ; n++) {1154 for (n = 0; n < SYMBOL_HASH_SIZE ; n++) {
729 symbol = symbolhash[n];1155 symbol = symbolhash[n];
730 while (symbol) {1156 while (symbol) {
731 symbol = symbol->next;1157 if (dump_sym(symbol))
732 }1158 buf_printf(&buf, "0x%08x\t%s\t%s\n",
733 }1159 symbol->crc, symbol->name,
734 1160 symbol->module->name);
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);
740 symbol = symbol->next;1161 symbol = symbol->next;
741 }1162 }
742 }1163 }
743 write_if_changed(&buf, fname);1164 write_if_changed(&buf, fname);
744}1165}
745 1166
746int1167int main(int argc, char **argv)
747main(int argc, char **argv)
748{1168{
749 struct module *mod;1169 struct module *mod;
750 struct buffer buf = { };1170 struct buffer buf = { };
751 char fname[SZ];1171 char fname[SZ];
752 char *dump_read = NULL, *dump_write = NULL;1172 char *kernel_read = NULL, *module_read = NULL;
1173 char *dump_write = NULL;
753 int opt;1174 int opt;
754 1175
755 while ((opt = getopt(argc, argv, "i:mo:a")) != -1) {1176 while ((opt = getopt(argc, argv, "i:I:mo:a")) != -1) {
756 switch(opt) {1177 switch(opt) {
757 case 'i':1178 case 'i':
758 dump_read = optarg;1179 kernel_read = optarg;
1180 break;
1181 case 'I':
1182 module_read = optarg;
1183 external_module = 1;
759 break;1184 break;
760 case 'm':1185 case 'm':
761 modversions = 1;1186 modversions = 1;
@@ -771,8 +1196,10 @@ main(int argc, char **argv) · 9 unmodified lines
771 }1196 }
772 }1197 }
773 1198
774 if (dump_read)1199 if (kernel_read)
775 read_dump(dump_read);1200 read_dump(kernel_read, 1);
1201 if (module_read)
1202 read_dump(module_read, 0);
776 1203
777 while (optind < argc) {1204 while (optind < argc) {
778 read_symbols(argv[optind++]);1205 read_symbols(argv[optind++]);
@@ -799,4 +1226,3 @@ main(int argc, char **argv) · 20 unmodified lines
799 1226
800 return 0;1227 return 0;
801}1228}
802
scripts/mod/modpost.h+20−5
@@ -13,20 +13,30 @@ · 12 unmodified lines
13 13
14#if KERNEL_ELFCLASS == ELFCLASS3214#if KERNEL_ELFCLASS == ELFCLASS32
15 15
16#define Elf_Ehdr Elf32_Ehdr 16#define Elf_Ehdr Elf32_Ehdr
17#define Elf_Shdr Elf32_Shdr 17#define Elf_Shdr Elf32_Shdr
18#define Elf_Sym Elf32_Sym18#define Elf_Sym Elf32_Sym
19#define Elf_Addr Elf32_Addr
20#define Elf_Section Elf32_Section
19#define ELF_ST_BIND ELF32_ST_BIND21#define ELF_ST_BIND ELF32_ST_BIND
20#define ELF_ST_TYPE ELF32_ST_TYPE22#define ELF_ST_TYPE ELF32_ST_TYPE
21 23
24#define Elf_Rela Elf32_Rela
25#define ELF_R_SYM ELF32_R_SYM
26#define ELF_R_TYPE ELF32_R_TYPE
22#else27#else
23 28
24#define Elf_Ehdr Elf64_Ehdr 29#define Elf_Ehdr Elf64_Ehdr
25#define Elf_Shdr Elf64_Shdr 30#define Elf_Shdr Elf64_Shdr
26#define Elf_Sym Elf64_Sym31#define Elf_Sym Elf64_Sym
32#define Elf_Addr Elf64_Addr
33#define Elf_Section Elf64_Section
27#define ELF_ST_BIND ELF64_ST_BIND34#define ELF_ST_BIND ELF64_ST_BIND
28#define ELF_ST_TYPE ELF64_ST_TYPE35#define ELF_ST_TYPE ELF64_ST_TYPE
29 36
37#define Elf_Rela Elf64_Rela
38#define ELF_R_SYM ELF64_R_SYM
39#define ELF_R_TYPE ELF64_R_TYPE
30#endif40#endif
31 41
32#if KERNEL_ELFDATA != HOST_ELFDATA42#if KERNEL_ELFDATA != HOST_ELFDATA
@@ -91,17 +101,22 @@ struct elf_info { · 58 unmodified lines
91 unsigned int modinfo_len;101 unsigned int modinfo_len;
92};102};
93 103
104/* file2alias.c */
94void handle_moddevtable(struct module *mod, struct elf_info *info,105void handle_moddevtable(struct module *mod, struct elf_info *info,
95 Elf_Sym *sym, const char *symname);106 Elf_Sym *sym, const char *symname);
96
97void add_moddevtable(struct buffer *buf, struct module *mod);107void add_moddevtable(struct buffer *buf, struct module *mod);
98 108
109/* sumversion.c */
99void maybe_frob_rcs_version(const char *modfilename,110void maybe_frob_rcs_version(const char *modfilename,
100 char *version,111 char *version,
101 void *modinfo,112 void *modinfo,
102 unsigned long modinfo_offset);113 unsigned long modinfo_offset);
103void get_src_version(const char *modname, char sum[], unsigned sumlen);114void get_src_version(const char *modname, char sum[], unsigned sumlen);
104 115
116/* from modpost.c */
105void *grab_file(const char *filename, unsigned long *size);117void *grab_file(const char *filename, unsigned long *size);
106char* get_next_line(unsigned long *pos, void *file, unsigned long size);118char* get_next_line(unsigned long *pos, void *file, unsigned long size);
107void release_file(void *file, unsigned long size);119void release_file(void *file, unsigned long size);
120
121void fatal(const char *fmt, ...);
122void 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
316 316
317 file = grab_file(cmd, &flen);317 file = grab_file(cmd, &flen);
318 if (!file) {318 if (!file) {
319 fprintf(stderr, "Warning: could not find %s for %s\n",319 warn("could not find %s for %s\n", cmd, objfile);
320 cmd, objfile);
321 goto out;320 goto out;
322 }321 }
323 322
@@ -355,9 +354,8 @@ static int parse_source_files(const char *objfile, struct md4_ctx *md) · 31 unmodified lines
355 /* Check if this file is in same dir as objfile */354 /* Check if this file is in same dir as objfile */
356 if ((strstr(line, dir)+strlen(dir)-1) == strrchr(line, '/')) {355 if ((strstr(line, dir)+strlen(dir)-1) == strrchr(line, '/')) {
357 if (!parse_file(line, md)) {356 if (!parse_file(line, md)) {
358 fprintf(stderr,357 warn("could not open %s: %s\n",
359 "Warning: could not open %s: %s\n",358 line, strerror(errno));
360 line, strerror(errno));
361 goto out_file;359 goto out_file;
362 }360 }
363 361
@@ -383,8 +381,11 @@ void get_src_version(const char *modname, char sum[], unsigned sumlen) · 19 unmodified lines
383 struct md4_ctx md;381 struct md4_ctx md;
384 char *sources, *end, *fname;382 char *sources, *end, *fname;
385 const char *basename;383 const char *basename;
386 char filelist[strlen(getenv("MODVERDIR")) + strlen("/") +384 char filelist[PATH_MAX + 1];
387 strlen(modname) - strlen(".o") + strlen(".mod") + 1 ];385 char *modverdir = getenv("MODVERDIR");
386
387 if (!modverdir)
388 modverdir = ".";
388 389
389 /* Source files for module are in .tmp_versions/modname.mod,390 /* Source files for module are in .tmp_versions/modname.mod,
390 after the first line. */391 after the first line. */
@@ -392,28 +393,25 @@ void get_src_version(const char *modname, char sum[], unsigned sumlen) · 1 unmodified line
392 basename = strrchr(modname, '/') + 1;393 basename = strrchr(modname, '/') + 1;
393 else394 else
394 basename = modname;395 basename = modname;
395 sprintf(filelist, "%s/%.*s.mod", getenv("MODVERDIR"),396 sprintf(filelist, "%s/%.*s.mod", modverdir,
396 (int) strlen(basename) - 2, basename);397 (int) strlen(basename) - 2, basename);
397 398
398 file = grab_file(filelist, &len);399 file = grab_file(filelist, &len);
399 if (!file) {400 if (!file) {
400 fprintf(stderr, "Warning: could not find versions for %s\n",401 warn("could not find versions for %s\n", filelist);
401 filelist);
402 return;402 return;
403 }403 }
404 404
405 sources = strchr(file, '\n');405 sources = strchr(file, '\n');
406 if (!sources) {406 if (!sources) {
407 fprintf(stderr, "Warning: malformed versions file for %s\n",407 warn("malformed versions file for %s\n", modname);
408 modname);
409 goto release;408 goto release;
410 }409 }
411 410
412 sources++;411 sources++;
413 end = strchr(sources, '\n');412 end = strchr(sources, '\n');
414 if (!end) {413 if (!end) {
415 fprintf(stderr, "Warning: bad ending versions file for %s\n",414 warn("bad ending versions file for %s\n", modname);
416 modname);
417 goto release;415 goto release;
418 }416 }
419 *end = '\0';417 *end = '\0';
@@ -438,19 +436,19 @@ static void write_version(const char *filename, const char *sum, · 18 unmodified lines
438 436
439 fd = open(filename, O_RDWR);437 fd = open(filename, O_RDWR);
440 if (fd < 0) {438 if (fd < 0) {
441 fprintf(stderr, "Warning: changing sum in %s failed: %s\n",439 warn("changing sum in %s failed: %s\n",
442 filename, strerror(errno));440 filename, strerror(errno));
443 return;441 return;
444 }442 }
445 443
446 if (lseek(fd, offset, SEEK_SET) == (off_t)-1) {444 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",
448 filename, offset, strerror(errno));446 filename, offset, strerror(errno));
449 goto out;447 goto out;
450 }448 }
451 449
452 if (write(fd, sum, strlen(sum)+1) != strlen(sum)+1) {450 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",
454 filename, strerror(errno));452 filename, strerror(errno));
455 goto out;453 goto out;
456 }454 }

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