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)
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
)
376 if (memcmp(symname
, MODULE_SYMBOL_PREFIX
,
377 strlen(MODULE_SYMBOL_PREFIX
)) == 0)
378 mod
->unres
= alloc_symbol(symname
+
379 strlen(MODULE_SYMBOL_PREFIX
),
380 ELF_ST_BIND(sym
->st_info
) == STB_WEAK
,
384 /* All exported symbols */
385 if (memcmp(symname
, KSYMTAB_PFX
, strlen(KSYMTAB_PFX
)) == 0) {
386 add_exported_symbol(symname
+ strlen(KSYMTAB_PFX
),
389 if (strcmp(symname
, MODULE_SYMBOL_PREFIX
"init_module") == 0)
391 if (strcmp(symname
, MODULE_SYMBOL_PREFIX
"cleanup_module") == 0)
392 mod
->has_cleanup
= 1;
398 is_vmlinux(const char *modname
)
402 if ((myname
= strrchr(modname
, '/')))
407 return strcmp(myname
, "vmlinux") == 0;
410 /* Parse tag=value strings from .modinfo section */
411 static char *next_string(char *string
, unsigned long *secsize
)
413 /* Skip non-zero chars */
416 if ((*secsize
)-- <= 1)
420 /* Skip any zero padding. */
423 if ((*secsize
)-- <= 1)
429 static char *get_modinfo(void *modinfo
, unsigned long modinfo_len
,
433 unsigned int taglen
= strlen(tag
);
434 unsigned long size
= modinfo_len
;
436 for (p
= modinfo
; p
; p
= next_string(p
, &size
)) {
437 if (strncmp(p
, tag
, taglen
) == 0 && p
[taglen
] == '=')
438 return p
+ taglen
+ 1;
444 read_symbols(char *modname
)
449 struct elf_info info
= { };
452 parse_elf(&info
, modname
);
454 mod
= new_module(modname
);
456 /* When there's no vmlinux, don't print warnings about
457 * unresolved symbols (since there'll be too many ;) */
458 if (is_vmlinux(modname
)) {
459 unsigned int fake_crc
= 0;
461 add_exported_symbol("struct_module", mod
, &fake_crc
);
465 for (sym
= info
.symtab_start
; sym
< info
.symtab_stop
; sym
++) {
466 symname
= info
.strtab
+ sym
->st_name
;
468 handle_modversions(mod
, &info
, sym
, symname
);
469 handle_moddevtable(mod
, &info
, sym
, symname
);
472 version
= get_modinfo(info
.modinfo
, info
.modinfo_len
, "version");
474 maybe_frob_rcs_version(modname
, version
, info
.modinfo
,
475 version
- (char *)info
.hdr
);
476 if (version
|| (all_versions
&& !is_vmlinux(modname
)))
477 get_src_version(modname
, mod
->srcversion
,
478 sizeof(mod
->srcversion
)-1);
480 parse_elf_finish(&info
);
482 /* Our trick to get versioning for struct_module - it's
483 * never passed as an argument to an exported function, so
484 * the automatic versioning doesn't pick it up, but it's really
485 * important anyhow */
487 mod
->unres
= alloc_symbol("struct_module", 0, mod
->unres
);
492 /* We first write the generated file into memory using the
493 * following helper, then compare to the file on disk and
494 * only update the later if anything changed */
496 void __attribute__((format(printf
, 2, 3)))
497 buf_printf(struct buffer
*buf
, const char *fmt
, ...)
504 len
= vsnprintf(tmp
, SZ
, fmt
, ap
);
505 if (buf
->size
- buf
->pos
< len
+ 1) {
507 buf
->p
= realloc(buf
->p
, buf
->size
);
509 strncpy(buf
->p
+ buf
->pos
, tmp
, len
+ 1);
515 buf_write(struct buffer
*buf
, const char *s
, int len
)
517 if (buf
->size
- buf
->pos
< len
) {
519 buf
->p
= realloc(buf
->p
, buf
->size
);
521 strncpy(buf
->p
+ buf
->pos
, s
, len
);
525 /* Header for the generated file */
528 add_header(struct buffer
*b
, struct module
*mod
)
530 buf_printf(b
, "#include <linux/module.h>\n");
531 buf_printf(b
, "#include <linux/vermagic.h>\n");
532 buf_printf(b
, "#include <linux/compiler.h>\n");
534 buf_printf(b
, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n");
536 buf_printf(b
, "#undef unix\n"); /* We have a module called "unix" */
537 buf_printf(b
, "struct module __this_module\n");
538 buf_printf(b
, "__attribute__((section(\".gnu.linkonce.this_module\"))) = {\n");
539 buf_printf(b
, " .name = __stringify(KBUILD_MODNAME),\n");
541 buf_printf(b
, " .init = init_module,\n");
542 if (mod
->has_cleanup
)
543 buf_printf(b
, "#ifdef CONFIG_MODULE_UNLOAD\n"
544 " .exit = cleanup_module,\n"
546 buf_printf(b
, "};\n");
549 /* Record CRCs for unresolved symbols */
552 add_versions(struct buffer
*b
, struct module
*mod
)
554 struct symbol
*s
, *exp
;
556 for (s
= mod
->unres
; s
; s
= s
->next
) {
557 exp
= find_symbol(s
->name
);
558 if (!exp
|| exp
->module
== mod
) {
559 if (have_vmlinux
&& !s
->weak
)
560 fprintf(stderr
, "*** Warning: \"%s\" [%s.ko] "
561 "undefined!\n", s
->name
, mod
->name
);
564 s
->module
= exp
->module
;
565 s
->crc_valid
= exp
->crc_valid
;
573 buf_printf(b
, "static const struct modversion_info ____versions[]\n");
574 buf_printf(b
, "__attribute_used__\n");
575 buf_printf(b
, "__attribute__((section(\"__versions\"))) = {\n");
577 for (s
= mod
->unres
; s
; s
= s
->next
) {
582 fprintf(stderr
, "*** Warning: \"%s\" [%s.ko] "
587 buf_printf(b
, "\t{ %#8x, \"%s\" },\n", s
->crc
, s
->name
);
590 buf_printf(b
, "};\n");
594 add_depends(struct buffer
*b
, struct module
*mod
, struct module
*modules
)
600 for (m
= modules
; m
; m
= m
->next
) {
601 m
->seen
= is_vmlinux(m
->name
);
605 buf_printf(b
, "static const char __module_depends[]\n");
606 buf_printf(b
, "__attribute_used__\n");
607 buf_printf(b
, "__attribute__((section(\".modinfo\"))) =\n");
608 buf_printf(b
, "\"depends=");
609 for (s
= mod
->unres
; s
; s
= s
->next
) {
617 buf_printf(b
, "%s%s", first
? "" : ",",
618 strrchr(s
->module
->name
, '/') + 1);
621 buf_printf(b
, "\";\n");
625 add_srcversion(struct buffer
*b
, struct module
*mod
)
627 if (mod
->srcversion
[0]) {
629 buf_printf(b
, "MODULE_INFO(srcversion, \"%s\");\n",
635 write_if_changed(struct buffer
*b
, const char *fname
)
641 file
= fopen(fname
, "r");
645 if (fstat(fileno(file
), &st
) < 0)
648 if (st
.st_size
!= b
->pos
)
651 tmp
= NOFAIL(malloc(b
->pos
));
652 if (fread(tmp
, 1, b
->pos
, file
) != b
->pos
)
655 if (memcmp(tmp
, b
->p
, b
->pos
) != 0)
667 file
= fopen(fname
, "w");
672 if (fwrite(b
->p
, 1, b
->pos
, file
) != b
->pos
) {
680 read_dump(const char *fname
)
682 unsigned long size
, pos
= 0;
683 void *file
= grab_file(fname
, &size
);
687 /* No symbol versions, silently ignore */
690 while ((line
= get_next_line(&pos
, file
, size
))) {
691 char *symname
, *modname
, *d
;
695 if (!(symname
= strchr(line
, '\t')))
698 if (!(modname
= strchr(symname
, '\t')))
701 if (strchr(modname
, '\t'))
703 crc
= strtoul(line
, &d
, 16);
704 if (*symname
== '\0' || *modname
== '\0' || *d
!= '\0')
707 if (!(mod
= find_module(modname
))) {
708 if (is_vmlinux(modname
)) {
711 mod
= new_module(NOFAIL(strdup(modname
)));
714 add_exported_symbol(symname
, mod
, &crc
);
718 fatal("parse error in symbol dump file\n");
722 write_dump(const char *fname
)
724 struct buffer buf
= { };
725 struct symbol
*symbol
;
728 for (n
= 0; n
< SYMBOL_HASH_SIZE
; n
++) {
729 symbol
= symbolhash
[n
];
731 symbol
= symbol
->next
;
735 for (n
= 0; n
< SYMBOL_HASH_SIZE
; n
++) {
736 symbol
= symbolhash
[n
];
738 buf_printf(&buf
, "0x%08x\t%s\t%s\n", symbol
->crc
,
739 symbol
->name
, symbol
->module
->name
);
740 symbol
= symbol
->next
;
743 write_if_changed(&buf
, fname
);
747 main(int argc
, char **argv
)
750 struct buffer buf
= { };
752 char *dump_read
= NULL
, *dump_write
= NULL
;
755 while ((opt
= getopt(argc
, argv
, "i:mo:a")) != -1) {
775 read_dump(dump_read
);
777 while (optind
< argc
) {
778 read_symbols(argv
[optind
++]);
781 for (mod
= modules
; mod
; mod
= mod
->next
) {
787 add_header(&buf
, mod
);
788 add_versions(&buf
, mod
);
789 add_depends(&buf
, mod
, modules
);
790 add_moddevtable(&buf
, mod
);
791 add_srcversion(&buf
, mod
);
793 sprintf(fname
, "%s.mod.c", mod
->name
);
794 write_if_changed(&buf
, fname
);
798 write_dump(dump_write
);