1 /* Postprocess module symbol versions
3 * Copyright 2003 Kai Germaschewski
4 * Copyright 2002-2004 Rusty Russell, IBM Corporation
6 * Based in part on module-init-tools/depmod.c,file2alias
8 * This software may be used and distributed according to the terms
9 * of the GNU General Public License, incorporated herein by reference.
11 * Usage: modpost vmlinux module1.o module2.o ...
17 /* Are we using CONFIG_MODVERSIONS? */
19 /* Warn about undefined symbols? (do so if we have vmlinux) */
21 /* Is CONFIG_MODULE_SRCVERSION_ALL set? */
22 static int all_versions
= 0;
25 fatal(const char *fmt
, ...)
29 fprintf(stderr
, "FATAL: ");
31 va_start(arglist
, fmt
);
32 vfprintf(stderr
, fmt
, arglist
);
39 warn(const char *fmt
, ...)
43 fprintf(stderr
, "WARNING: ");
45 va_start(arglist
, fmt
);
46 vfprintf(stderr
, fmt
, arglist
);
50 void *do_nofail(void *ptr
, const char *expr
)
53 fatal("modpost: Memory allocation failure: %s.\n", expr
);
58 /* A list of all modules we processed */
60 static struct module
*modules
;
63 find_module(char *modname
)
67 for (mod
= modules
; mod
; mod
= mod
->next
)
68 if (strcmp(mod
->name
, modname
) == 0)
74 new_module(char *modname
)
79 mod
= NOFAIL(malloc(sizeof(*mod
)));
80 memset(mod
, 0, sizeof(*mod
));
81 p
= NOFAIL(strdup(modname
));
83 /* strip trailing .o */
84 if ((s
= strrchr(p
, '.')) != NULL
)
85 if (strcmp(s
, ".o") == 0)
96 /* A hash of all exported symbols,
97 * struct symbol is also used for lists of unresolved symbols */
99 #define SYMBOL_HASH_SIZE 1024
103 struct module
*module
;
110 static struct symbol
*symbolhash
[SYMBOL_HASH_SIZE
];
112 /* This is based on the hash agorithm from gdbm, via tdb */
113 static inline unsigned int tdb_hash(const char *name
)
115 unsigned value
; /* Used to compute the hash value. */
116 unsigned i
; /* Used to cycle through random values. */
118 /* Set the initial value from the key size. */
119 for (value
= 0x238F13AF * strlen(name
), i
=0; name
[i
]; i
++)
120 value
= (value
+ (((unsigned char *)name
)[i
] << (i
*5 % 24)));
122 return (1103515243 * value
+ 12345);
125 /* Allocate a new symbols for use in the hash of exported symbols or
126 * the list of unresolved symbols per module */
129 alloc_symbol(const char *name
, unsigned int weak
, struct symbol
*next
)
131 struct symbol
*s
= NOFAIL(malloc(sizeof(*s
) + strlen(name
) + 1));
133 memset(s
, 0, sizeof(*s
));
134 strcpy(s
->name
, name
);
140 /* For the hash of exported symbols */
143 new_symbol(const char *name
, struct module
*module
, unsigned int *crc
)
148 hash
= tdb_hash(name
) % SYMBOL_HASH_SIZE
;
149 new = symbolhash
[hash
] = alloc_symbol(name
, 0, symbolhash
[hash
]);
150 new->module
= module
;
158 find_symbol(const char *name
)
162 /* For our purposes, .foo matches foo. PPC64 needs this. */
166 for (s
= symbolhash
[tdb_hash(name
) % SYMBOL_HASH_SIZE
]; s
; s
=s
->next
) {
167 if (strcmp(s
->name
, name
) == 0)
173 /* Add an exported symbol - it may have already been added without a
174 * CRC, in this case just update the CRC */
176 add_exported_symbol(const char *name
, struct module
*module
, unsigned int *crc
)
178 struct symbol
*s
= find_symbol(name
);
181 new_symbol(name
, module
, crc
);
191 grab_file(const char *filename
, unsigned long *size
)
197 fd
= open(filename
, O_RDONLY
);
198 if (fd
< 0 || fstat(fd
, &st
) != 0)
202 map
= mmap(NULL
, *size
, PROT_READ
|PROT_WRITE
, MAP_PRIVATE
, fd
, 0);
205 if (map
== MAP_FAILED
)
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.
216 get_next_line(unsigned long *pos
, void *file
, unsigned long size
)
218 static char line
[4096];
221 signed char *p
= (signed char *)file
+ *pos
;
224 for (; *pos
< size
; (*pos
)++)
226 if (skip
&& isspace(*p
)) {
231 if (*p
!= '\n' && (*pos
< size
)) {
235 break; /* Too long, stop */
247 release_file(void *file
, unsigned long size
)
253 parse_elf(struct elf_info
*info
, const char *filename
)
256 Elf_Ehdr
*hdr
= info
->hdr
;
260 hdr
= grab_file(filename
, &info
->size
);
266 if (info
->size
< sizeof(*hdr
))
269 /* Fix endianness in ELF header */
270 hdr
->e_shoff
= TO_NATIVE(hdr
->e_shoff
);
271 hdr
->e_shstrndx
= TO_NATIVE(hdr
->e_shstrndx
);
272 hdr
->e_shnum
= TO_NATIVE(hdr
->e_shnum
);
273 hdr
->e_machine
= TO_NATIVE(hdr
->e_machine
);
274 sechdrs
= (void *)hdr
+ hdr
->e_shoff
;
275 info
->sechdrs
= sechdrs
;
277 /* Fix endianness in section headers */
278 for (i
= 0; i
< hdr
->e_shnum
; i
++) {
279 sechdrs
[i
].sh_type
= TO_NATIVE(sechdrs
[i
].sh_type
);
280 sechdrs
[i
].sh_offset
= TO_NATIVE(sechdrs
[i
].sh_offset
);
281 sechdrs
[i
].sh_size
= TO_NATIVE(sechdrs
[i
].sh_size
);
282 sechdrs
[i
].sh_link
= TO_NATIVE(sechdrs
[i
].sh_link
);
283 sechdrs
[i
].sh_name
= TO_NATIVE(sechdrs
[i
].sh_name
);
285 /* Find symbol table. */
286 for (i
= 1; i
< hdr
->e_shnum
; i
++) {
287 const char *secstrings
288 = (void *)hdr
+ sechdrs
[hdr
->e_shstrndx
].sh_offset
;
290 if (sechdrs
[i
].sh_offset
> info
->size
)
292 if (strcmp(secstrings
+sechdrs
[i
].sh_name
, ".modinfo") == 0) {
293 info
->modinfo
= (void *)hdr
+ sechdrs
[i
].sh_offset
;
294 info
->modinfo_len
= sechdrs
[i
].sh_size
;
296 if (sechdrs
[i
].sh_type
!= SHT_SYMTAB
)
299 info
->symtab_start
= (void *)hdr
+ sechdrs
[i
].sh_offset
;
300 info
->symtab_stop
= (void *)hdr
+ sechdrs
[i
].sh_offset
301 + sechdrs
[i
].sh_size
;
302 info
->strtab
= (void *)hdr
+
303 sechdrs
[sechdrs
[i
].sh_link
].sh_offset
;
305 if (!info
->symtab_start
) {
306 fprintf(stderr
, "modpost: %s no symtab?\n", filename
);
309 /* Fix endianness in symbols */
310 for (sym
= info
->symtab_start
; sym
< info
->symtab_stop
; sym
++) {
311 sym
->st_shndx
= TO_NATIVE(sym
->st_shndx
);
312 sym
->st_name
= TO_NATIVE(sym
->st_name
);
313 sym
->st_value
= TO_NATIVE(sym
->st_value
);
314 sym
->st_size
= TO_NATIVE(sym
->st_size
);
319 fprintf(stderr
, "modpost: %s is truncated.\n", filename
);
324 parse_elf_finish(struct elf_info
*info
)
326 release_file(info
->hdr
, info
->size
);
329 #define CRC_PFX MODULE_SYMBOL_PREFIX "__crc_"
330 #define KSYMTAB_PFX MODULE_SYMBOL_PREFIX "__ksymtab_"
333 handle_modversions(struct module
*mod
, struct elf_info
*info
,
334 Elf_Sym
*sym
, const char *symname
)
338 switch (sym
->st_shndx
) {
340 fprintf(stderr
, "*** Warning: \"%s\" [%s] is COMMON symbol\n",
345 if (memcmp(symname
, CRC_PFX
, strlen(CRC_PFX
)) == 0) {
346 crc
= (unsigned int) sym
->st_value
;
347 add_exported_symbol(symname
+ strlen(CRC_PFX
),
352 /* undefined symbol */
353 if (ELF_ST_BIND(sym
->st_info
) != STB_GLOBAL
&&
354 ELF_ST_BIND(sym
->st_info
) != STB_WEAK
)
356 /* ignore global offset table */
357 if (strcmp(symname
, "_GLOBAL_OFFSET_TABLE_") == 0)
359 /* ignore __this_module, it will be resolved shortly */
360 if (strcmp(symname
, MODULE_SYMBOL_PREFIX
"__this_module") == 0)
363 if (info
->hdr
->e_machine
== EM_SPARC
||
364 info
->hdr
->e_machine
== EM_SPARCV9
) {
365 /* Ignore register directives. */
366 if (ELF_ST_TYPE(sym
->st_info
) == STT_REGISTER
)
371 if (memcmp(symname
, MODULE_SYMBOL_PREFIX
,
372 strlen(MODULE_SYMBOL_PREFIX
)) == 0)
373 mod
->unres
= alloc_symbol(symname
+
374 strlen(MODULE_SYMBOL_PREFIX
),
375 ELF_ST_BIND(sym
->st_info
) == STB_WEAK
,
379 /* All exported symbols */
380 if (memcmp(symname
, KSYMTAB_PFX
, strlen(KSYMTAB_PFX
)) == 0) {
381 add_exported_symbol(symname
+ strlen(KSYMTAB_PFX
),
384 if (strcmp(symname
, MODULE_SYMBOL_PREFIX
"init_module") == 0)
386 if (strcmp(symname
, MODULE_SYMBOL_PREFIX
"cleanup_module") == 0)
387 mod
->has_cleanup
= 1;
393 is_vmlinux(const char *modname
)
397 if ((myname
= strrchr(modname
, '/')))
402 return strcmp(myname
, "vmlinux") == 0;
405 /* Parse tag=value strings from .modinfo section */
406 static char *next_string(char *string
, unsigned long *secsize
)
408 /* Skip non-zero chars */
411 if ((*secsize
)-- <= 1)
415 /* Skip any zero padding. */
418 if ((*secsize
)-- <= 1)
424 static char *get_modinfo(void *modinfo
, unsigned long modinfo_len
,
428 unsigned int taglen
= strlen(tag
);
429 unsigned long size
= modinfo_len
;
431 for (p
= modinfo
; p
; p
= next_string(p
, &size
)) {
432 if (strncmp(p
, tag
, taglen
) == 0 && p
[taglen
] == '=')
433 return p
+ taglen
+ 1;
439 read_symbols(char *modname
)
444 struct elf_info info
= { };
447 parse_elf(&info
, modname
);
449 mod
= new_module(modname
);
451 /* When there's no vmlinux, don't print warnings about
452 * unresolved symbols (since there'll be too many ;) */
453 if (is_vmlinux(modname
)) {
454 unsigned int fake_crc
= 0;
456 add_exported_symbol("struct_module", mod
, &fake_crc
);
460 for (sym
= info
.symtab_start
; sym
< info
.symtab_stop
; sym
++) {
461 symname
= info
.strtab
+ sym
->st_name
;
463 handle_modversions(mod
, &info
, sym
, symname
);
464 handle_moddevtable(mod
, &info
, sym
, symname
);
467 version
= get_modinfo(info
.modinfo
, info
.modinfo_len
, "version");
469 maybe_frob_rcs_version(modname
, version
, info
.modinfo
,
470 version
- (char *)info
.hdr
);
471 if (version
|| (all_versions
&& !is_vmlinux(modname
)))
472 get_src_version(modname
, mod
->srcversion
,
473 sizeof(mod
->srcversion
)-1);
475 parse_elf_finish(&info
);
477 /* Our trick to get versioning for struct_module - it's
478 * never passed as an argument to an exported function, so
479 * the automatic versioning doesn't pick it up, but it's really
480 * important anyhow */
482 mod
->unres
= alloc_symbol("struct_module", 0, mod
->unres
);
487 /* We first write the generated file into memory using the
488 * following helper, then compare to the file on disk and
489 * only update the later if anything changed */
491 void __attribute__((format(printf
, 2, 3)))
492 buf_printf(struct buffer
*buf
, const char *fmt
, ...)
499 len
= vsnprintf(tmp
, SZ
, fmt
, ap
);
500 if (buf
->size
- buf
->pos
< len
+ 1) {
502 buf
->p
= realloc(buf
->p
, buf
->size
);
504 strncpy(buf
->p
+ buf
->pos
, tmp
, len
+ 1);
510 buf_write(struct buffer
*buf
, const char *s
, int len
)
512 if (buf
->size
- buf
->pos
< len
) {
514 buf
->p
= realloc(buf
->p
, buf
->size
);
516 strncpy(buf
->p
+ buf
->pos
, s
, len
);
520 /* Header for the generated file */
523 add_header(struct buffer
*b
, struct module
*mod
)
525 buf_printf(b
, "#include <linux/module.h>\n");
526 buf_printf(b
, "#include <linux/vermagic.h>\n");
527 buf_printf(b
, "#include <linux/compiler.h>\n");
529 buf_printf(b
, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n");
531 buf_printf(b
, "#undef unix\n"); /* We have a module called "unix" */
532 buf_printf(b
, "struct module __this_module\n");
533 buf_printf(b
, "__attribute__((section(\".gnu.linkonce.this_module\"))) = {\n");
534 buf_printf(b
, " .name = __stringify(KBUILD_MODNAME),\n");
536 buf_printf(b
, " .init = init_module,\n");
537 if (mod
->has_cleanup
)
538 buf_printf(b
, "#ifdef CONFIG_MODULE_UNLOAD\n"
539 " .exit = cleanup_module,\n"
541 buf_printf(b
, "};\n");
544 /* Record CRCs for unresolved symbols */
547 add_versions(struct buffer
*b
, struct module
*mod
)
549 struct symbol
*s
, *exp
;
551 for (s
= mod
->unres
; s
; s
= s
->next
) {
552 exp
= find_symbol(s
->name
);
553 if (!exp
|| exp
->module
== mod
) {
554 if (have_vmlinux
&& !s
->weak
)
555 fprintf(stderr
, "*** Warning: \"%s\" [%s.ko] "
556 "undefined!\n", s
->name
, mod
->name
);
559 s
->module
= exp
->module
;
560 s
->crc_valid
= exp
->crc_valid
;
568 buf_printf(b
, "static const struct modversion_info ____versions[]\n");
569 buf_printf(b
, "__attribute_used__\n");
570 buf_printf(b
, "__attribute__((section(\"__versions\"))) = {\n");
572 for (s
= mod
->unres
; s
; s
= s
->next
) {
577 fprintf(stderr
, "*** Warning: \"%s\" [%s.ko] "
582 buf_printf(b
, "\t{ %#8x, \"%s\" },\n", s
->crc
, s
->name
);
585 buf_printf(b
, "};\n");
589 add_depends(struct buffer
*b
, struct module
*mod
, struct module
*modules
)
595 for (m
= modules
; m
; m
= m
->next
) {
596 m
->seen
= is_vmlinux(m
->name
);
600 buf_printf(b
, "static const char __module_depends[]\n");
601 buf_printf(b
, "__attribute_used__\n");
602 buf_printf(b
, "__attribute__((section(\".modinfo\"))) =\n");
603 buf_printf(b
, "\"depends=");
604 for (s
= mod
->unres
; s
; s
= s
->next
) {
612 buf_printf(b
, "%s%s", first
? "" : ",",
613 strrchr(s
->module
->name
, '/') + 1);
616 buf_printf(b
, "\";\n");
620 add_srcversion(struct buffer
*b
, struct module
*mod
)
622 if (mod
->srcversion
[0]) {
624 buf_printf(b
, "MODULE_INFO(srcversion, \"%s\");\n",
630 write_if_changed(struct buffer
*b
, const char *fname
)
636 file
= fopen(fname
, "r");
640 if (fstat(fileno(file
), &st
) < 0)
643 if (st
.st_size
!= b
->pos
)
646 tmp
= NOFAIL(malloc(b
->pos
));
647 if (fread(tmp
, 1, b
->pos
, file
) != b
->pos
)
650 if (memcmp(tmp
, b
->p
, b
->pos
) != 0)
662 file
= fopen(fname
, "w");
667 if (fwrite(b
->p
, 1, b
->pos
, file
) != b
->pos
) {
675 read_dump(const char *fname
)
677 unsigned long size
, pos
= 0;
678 void *file
= grab_file(fname
, &size
);
682 /* No symbol versions, silently ignore */
685 while ((line
= get_next_line(&pos
, file
, size
))) {
686 char *symname
, *modname
, *d
;
690 if (!(symname
= strchr(line
, '\t')))
693 if (!(modname
= strchr(symname
, '\t')))
696 if (strchr(modname
, '\t'))
698 crc
= strtoul(line
, &d
, 16);
699 if (*symname
== '\0' || *modname
== '\0' || *d
!= '\0')
702 if (!(mod
= find_module(modname
))) {
703 if (is_vmlinux(modname
)) {
706 mod
= new_module(NOFAIL(strdup(modname
)));
709 add_exported_symbol(symname
, mod
, &crc
);
713 fatal("parse error in symbol dump file\n");
717 write_dump(const char *fname
)
719 struct buffer buf
= { };
720 struct symbol
*symbol
;
723 for (n
= 0; n
< SYMBOL_HASH_SIZE
; n
++) {
724 symbol
= symbolhash
[n
];
726 symbol
= symbol
->next
;
730 for (n
= 0; n
< SYMBOL_HASH_SIZE
; n
++) {
731 symbol
= symbolhash
[n
];
733 buf_printf(&buf
, "0x%08x\t%s\t%s\n", symbol
->crc
,
734 symbol
->name
, symbol
->module
->name
);
735 symbol
= symbol
->next
;
738 write_if_changed(&buf
, fname
);
742 main(int argc
, char **argv
)
745 struct buffer buf
= { };
747 char *dump_read
= NULL
, *dump_write
= NULL
;
750 while ((opt
= getopt(argc
, argv
, "i:mo:a")) != -1) {
770 read_dump(dump_read
);
772 while (optind
< argc
) {
773 read_symbols(argv
[optind
++]);
776 for (mod
= modules
; mod
; mod
= mod
->next
) {
782 add_header(&buf
, mod
);
783 add_versions(&buf
, mod
);
784 add_depends(&buf
, mod
, modules
);
785 add_moddevtable(&buf
, mod
);
786 add_srcversion(&buf
, mod
);
788 sprintf(fname
, "%s.mod.c", mod
->name
);
789 write_if_changed(&buf
, fname
);
793 write_dump(dump_write
);