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 "__crc_"
330 #define KSYMTAB_PFX "__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)
362 /* cope with newer glibc (2.3.4 or higher) STT_ definition in elf.h */
363 #if defined(STT_REGISTER) || defined(STT_SPARC_REGISTER)
364 /* add compatibility with older glibc */
365 #ifndef STT_SPARC_REGISTER
366 #define STT_SPARC_REGISTER STT_REGISTER
368 if (info
->hdr
->e_machine
== EM_SPARC
||
369 info
->hdr
->e_machine
== EM_SPARCV9
) {
370 /* Ignore register directives. */
371 if (ELF_ST_TYPE(sym
->st_info
) == STT_SPARC_REGISTER
)
373 if (symname
[0] == '.') {
374 char *munged
= strdup(symname
);
376 munged
[1] = toupper(munged
[1]);
382 if (memcmp(symname
, MODULE_SYMBOL_PREFIX
,
383 strlen(MODULE_SYMBOL_PREFIX
)) == 0)
384 mod
->unres
= alloc_symbol(symname
+
385 strlen(MODULE_SYMBOL_PREFIX
),
386 ELF_ST_BIND(sym
->st_info
) == STB_WEAK
,
390 /* All exported symbols */
391 if (memcmp(symname
, KSYMTAB_PFX
, strlen(KSYMTAB_PFX
)) == 0) {
392 add_exported_symbol(symname
+ strlen(KSYMTAB_PFX
),
395 if (strcmp(symname
, MODULE_SYMBOL_PREFIX
"init_module") == 0)
397 if (strcmp(symname
, MODULE_SYMBOL_PREFIX
"cleanup_module") == 0)
398 mod
->has_cleanup
= 1;
404 is_vmlinux(const char *modname
)
408 if ((myname
= strrchr(modname
, '/')))
413 return strcmp(myname
, "vmlinux") == 0;
416 /* Parse tag=value strings from .modinfo section */
417 static char *next_string(char *string
, unsigned long *secsize
)
419 /* Skip non-zero chars */
422 if ((*secsize
)-- <= 1)
426 /* Skip any zero padding. */
429 if ((*secsize
)-- <= 1)
435 static char *get_modinfo(void *modinfo
, unsigned long modinfo_len
,
439 unsigned int taglen
= strlen(tag
);
440 unsigned long size
= modinfo_len
;
442 for (p
= modinfo
; p
; p
= next_string(p
, &size
)) {
443 if (strncmp(p
, tag
, taglen
) == 0 && p
[taglen
] == '=')
444 return p
+ taglen
+ 1;
450 read_symbols(char *modname
)
455 struct elf_info info
= { };
458 parse_elf(&info
, modname
);
460 mod
= new_module(modname
);
462 /* When there's no vmlinux, don't print warnings about
463 * unresolved symbols (since there'll be too many ;) */
464 if (is_vmlinux(modname
)) {
465 unsigned int fake_crc
= 0;
467 add_exported_symbol("struct_module", mod
, &fake_crc
);
471 for (sym
= info
.symtab_start
; sym
< info
.symtab_stop
; sym
++) {
472 symname
= info
.strtab
+ sym
->st_name
;
474 handle_modversions(mod
, &info
, sym
, symname
);
475 handle_moddevtable(mod
, &info
, sym
, symname
);
478 version
= get_modinfo(info
.modinfo
, info
.modinfo_len
, "version");
480 maybe_frob_rcs_version(modname
, version
, info
.modinfo
,
481 version
- (char *)info
.hdr
);
482 if (version
|| (all_versions
&& !is_vmlinux(modname
)))
483 get_src_version(modname
, mod
->srcversion
,
484 sizeof(mod
->srcversion
)-1);
486 parse_elf_finish(&info
);
488 /* Our trick to get versioning for struct_module - it's
489 * never passed as an argument to an exported function, so
490 * the automatic versioning doesn't pick it up, but it's really
491 * important anyhow */
493 mod
->unres
= alloc_symbol("struct_module", 0, mod
->unres
);
498 /* We first write the generated file into memory using the
499 * following helper, then compare to the file on disk and
500 * only update the later if anything changed */
502 void __attribute__((format(printf
, 2, 3)))
503 buf_printf(struct buffer
*buf
, const char *fmt
, ...)
510 len
= vsnprintf(tmp
, SZ
, fmt
, ap
);
511 if (buf
->size
- buf
->pos
< len
+ 1) {
513 buf
->p
= realloc(buf
->p
, buf
->size
);
515 strncpy(buf
->p
+ buf
->pos
, tmp
, len
+ 1);
521 buf_write(struct buffer
*buf
, const char *s
, int len
)
523 if (buf
->size
- buf
->pos
< len
) {
525 buf
->p
= realloc(buf
->p
, buf
->size
);
527 strncpy(buf
->p
+ buf
->pos
, s
, len
);
531 /* Header for the generated file */
534 add_header(struct buffer
*b
, struct module
*mod
)
536 buf_printf(b
, "#include <linux/module.h>\n");
537 buf_printf(b
, "#include <linux/vermagic.h>\n");
538 buf_printf(b
, "#include <linux/compiler.h>\n");
540 buf_printf(b
, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n");
542 buf_printf(b
, "struct module __this_module\n");
543 buf_printf(b
, "__attribute__((section(\".gnu.linkonce.this_module\"))) = {\n");
544 buf_printf(b
, " .name = KBUILD_MODNAME,\n");
546 buf_printf(b
, " .init = init_module,\n");
547 if (mod
->has_cleanup
)
548 buf_printf(b
, "#ifdef CONFIG_MODULE_UNLOAD\n"
549 " .exit = cleanup_module,\n"
551 buf_printf(b
, "};\n");
554 /* Record CRCs for unresolved symbols */
557 add_versions(struct buffer
*b
, struct module
*mod
)
559 struct symbol
*s
, *exp
;
561 for (s
= mod
->unres
; s
; s
= s
->next
) {
562 exp
= find_symbol(s
->name
);
563 if (!exp
|| exp
->module
== mod
) {
564 if (have_vmlinux
&& !s
->weak
)
565 fprintf(stderr
, "*** Warning: \"%s\" [%s.ko] "
566 "undefined!\n", s
->name
, mod
->name
);
569 s
->module
= exp
->module
;
570 s
->crc_valid
= exp
->crc_valid
;
578 buf_printf(b
, "static const struct modversion_info ____versions[]\n");
579 buf_printf(b
, "__attribute_used__\n");
580 buf_printf(b
, "__attribute__((section(\"__versions\"))) = {\n");
582 for (s
= mod
->unres
; s
; s
= s
->next
) {
587 fprintf(stderr
, "*** Warning: \"%s\" [%s.ko] "
592 buf_printf(b
, "\t{ %#8x, \"%s\" },\n", s
->crc
, s
->name
);
595 buf_printf(b
, "};\n");
599 add_depends(struct buffer
*b
, struct module
*mod
, struct module
*modules
)
605 for (m
= modules
; m
; m
= m
->next
) {
606 m
->seen
= is_vmlinux(m
->name
);
610 buf_printf(b
, "static const char __module_depends[]\n");
611 buf_printf(b
, "__attribute_used__\n");
612 buf_printf(b
, "__attribute__((section(\".modinfo\"))) =\n");
613 buf_printf(b
, "\"depends=");
614 for (s
= mod
->unres
; s
; s
= s
->next
) {
622 buf_printf(b
, "%s%s", first
? "" : ",",
623 strrchr(s
->module
->name
, '/') + 1);
626 buf_printf(b
, "\";\n");
630 add_srcversion(struct buffer
*b
, struct module
*mod
)
632 if (mod
->srcversion
[0]) {
634 buf_printf(b
, "MODULE_INFO(srcversion, \"%s\");\n",
640 write_if_changed(struct buffer
*b
, const char *fname
)
646 file
= fopen(fname
, "r");
650 if (fstat(fileno(file
), &st
) < 0)
653 if (st
.st_size
!= b
->pos
)
656 tmp
= NOFAIL(malloc(b
->pos
));
657 if (fread(tmp
, 1, b
->pos
, file
) != b
->pos
)
660 if (memcmp(tmp
, b
->p
, b
->pos
) != 0)
672 file
= fopen(fname
, "w");
677 if (fwrite(b
->p
, 1, b
->pos
, file
) != b
->pos
) {
685 read_dump(const char *fname
)
687 unsigned long size
, pos
= 0;
688 void *file
= grab_file(fname
, &size
);
692 /* No symbol versions, silently ignore */
695 while ((line
= get_next_line(&pos
, file
, size
))) {
696 char *symname
, *modname
, *d
;
700 if (!(symname
= strchr(line
, '\t')))
703 if (!(modname
= strchr(symname
, '\t')))
706 if (strchr(modname
, '\t'))
708 crc
= strtoul(line
, &d
, 16);
709 if (*symname
== '\0' || *modname
== '\0' || *d
!= '\0')
712 if (!(mod
= find_module(modname
))) {
713 if (is_vmlinux(modname
)) {
716 mod
= new_module(NOFAIL(strdup(modname
)));
719 add_exported_symbol(symname
, mod
, &crc
);
723 fatal("parse error in symbol dump file\n");
727 write_dump(const char *fname
)
729 struct buffer buf
= { };
730 struct symbol
*symbol
;
733 for (n
= 0; n
< SYMBOL_HASH_SIZE
; n
++) {
734 symbol
= symbolhash
[n
];
736 symbol
= symbol
->next
;
740 for (n
= 0; n
< SYMBOL_HASH_SIZE
; n
++) {
741 symbol
= symbolhash
[n
];
743 buf_printf(&buf
, "0x%08x\t%s\t%s\n", symbol
->crc
,
744 symbol
->name
, symbol
->module
->name
);
745 symbol
= symbol
->next
;
748 write_if_changed(&buf
, fname
);
752 main(int argc
, char **argv
)
755 struct buffer buf
= { };
757 char *dump_read
= NULL
, *dump_write
= NULL
;
760 while ((opt
= getopt(argc
, argv
, "i:mo:a")) != -1) {
780 read_dump(dump_read
);
782 while (optind
< argc
) {
783 read_symbols(argv
[optind
++]);
786 for (mod
= modules
; mod
; mod
= mod
->next
) {
792 add_header(&buf
, mod
);
793 add_versions(&buf
, mod
);
794 add_depends(&buf
, mod
, modules
);
795 add_moddevtable(&buf
, mod
);
796 add_srcversion(&buf
, mod
);
798 sprintf(fname
, "%s.mod.c", mod
->name
);
799 write_if_changed(&buf
, fname
);
803 write_dump(dump_write
);