[PATCH] create configuration in the destination directory
[linux-2.6/history.git] / scripts / modpost.c
blob13c33ccca090e55f520eed3ff7356b5e08f34534
1 /* Postprocess module symbol versions
3 * Copyright 2003 Kai Germaschewski
4 * 2002-2003 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 ...
14 #include "modpost.h"
16 /* Are we using CONFIG_MODVERSIONS? */
17 int modversions = 0;
18 /* Do we have vmlinux? */
19 int have_vmlinux = 0;
21 void
22 fatal(const char *fmt, ...)
24 va_list arglist;
26 fprintf(stderr, "FATAL: ");
28 va_start(arglist, fmt);
29 vfprintf(stderr, fmt, arglist);
30 va_end(arglist);
32 exit(1);
35 void
36 warn(const char *fmt, ...)
38 va_list arglist;
40 fprintf(stderr, "WARNING: ");
42 va_start(arglist, fmt);
43 vfprintf(stderr, fmt, arglist);
44 va_end(arglist);
47 #define NOFAIL(ptr) do_nofail((ptr), __FILE__, __LINE__, #ptr)
49 void *do_nofail(void *ptr, const char *file, int line, const char *expr)
51 if (!ptr) {
52 fatal("Memory allocation failure %s line %d: %s.\n",
53 file, line, expr);
55 return ptr;
58 /* A list of all modules we processed */
60 static struct module *modules;
62 struct module *
63 new_module(char *modname)
65 struct module *mod;
66 char *p;
68 /* strip trailing .o */
69 p = strstr(modname, ".o");
70 if (p)
71 *p = 0;
73 mod = NOFAIL(malloc(sizeof(*mod)));
74 memset(mod, 0, sizeof(*mod));
75 mod->name = modname;
77 /* add to list */
78 mod->next = modules;
79 modules = mod;
81 return mod;
84 /* A hash of all exported symbols,
85 * struct symbol is also used for lists of unresolved symbols */
87 #define SYMBOL_HASH_SIZE 1024
89 struct symbol {
90 struct symbol *next;
91 struct module *module;
92 unsigned int crc;
93 int crc_valid;
94 char name[0];
97 static struct symbol *symbolhash[SYMBOL_HASH_SIZE];
99 /* This is based on the hash agorithm from gdbm, via tdb */
100 static inline unsigned int tdb_hash(const char *name)
102 unsigned value; /* Used to compute the hash value. */
103 unsigned i; /* Used to cycle through random values. */
105 /* Set the initial value from the key size. */
106 for (value = 0x238F13AF * strlen(name), i=0; name[i]; i++)
107 value = (value + (((unsigned char *)name)[i] << (i*5 % 24)));
109 return (1103515243 * value + 12345);
112 /* Allocate a new symbols for use in the hash of exported symbols or
113 * the list of unresolved symbols per module */
115 struct symbol *
116 alloc_symbol(const char *name)
118 struct symbol *s = NOFAIL(malloc(sizeof(*s) + strlen(name) + 1));
120 memset(s, 0, sizeof(*s));
121 strcpy(s->name, name);
122 return s;
125 /* For the hash of exported symbols */
127 void
128 new_symbol(const char *name, struct module *module, unsigned int *crc)
130 unsigned int hash;
131 struct symbol *new = alloc_symbol(name);
133 new->module = module;
134 if (crc) {
135 new->crc = *crc;
136 new->crc_valid = 1;
139 hash = tdb_hash(name) % SYMBOL_HASH_SIZE;
140 new->next = symbolhash[hash];
141 symbolhash[hash] = new;
144 struct symbol *
145 find_symbol(const char *name)
147 struct symbol *s;
149 /* For our purposes, .foo matches foo. PPC64 needs this. */
150 if (name[0] == '.')
151 name++;
153 for (s = symbolhash[tdb_hash(name) % SYMBOL_HASH_SIZE]; s; s=s->next) {
154 if (strcmp(s->name, name) == 0)
155 return s;
157 return NULL;
160 /* Add an exported symbol - it may have already been added without a
161 * CRC, in this case just update the CRC */
162 void
163 add_exported_symbol(const char *name, struct module *module, unsigned int *crc)
165 struct symbol *s = find_symbol(name);
167 if (!s) {
168 new_symbol(name, modules, crc);
169 return;
171 if (crc) {
172 s->crc = *crc;
173 s->crc_valid = 1;
177 void *
178 grab_file(const char *filename, unsigned long *size)
180 struct stat st;
181 void *map;
182 int fd;
184 fd = open(filename, O_RDONLY);
185 if (fd < 0) {
186 perror(filename);
187 abort();
189 if (fstat(fd, &st) != 0) {
190 perror(filename);
191 abort();
194 *size = st.st_size;
195 map = mmap(NULL, *size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0);
196 if (mmap == MAP_FAILED) {
197 perror(filename);
198 abort();
200 close(fd);
201 return map;
204 void
205 parse_elf(struct elf_info *info, const char *filename)
207 unsigned int i;
208 Elf_Ehdr *hdr = info->hdr;
209 Elf_Shdr *sechdrs;
210 Elf_Sym *sym;
212 hdr = grab_file(filename, &info->size);
213 info->hdr = hdr;
214 if (info->size < sizeof(*hdr))
215 goto truncated;
217 /* Fix endianness in ELF header */
218 hdr->e_shoff = TO_NATIVE(hdr->e_shoff);
219 hdr->e_shstrndx = TO_NATIVE(hdr->e_shstrndx);
220 hdr->e_shnum = TO_NATIVE(hdr->e_shnum);
221 sechdrs = (void *)hdr + hdr->e_shoff;
222 info->sechdrs = sechdrs;
224 /* Fix endianness in section headers */
225 for (i = 0; i < hdr->e_shnum; i++) {
226 sechdrs[i].sh_type = TO_NATIVE(sechdrs[i].sh_type);
227 sechdrs[i].sh_offset = TO_NATIVE(sechdrs[i].sh_offset);
228 sechdrs[i].sh_size = TO_NATIVE(sechdrs[i].sh_size);
229 sechdrs[i].sh_link = TO_NATIVE(sechdrs[i].sh_link);
231 /* Find symbol table. */
232 for (i = 1; i < hdr->e_shnum; i++) {
233 if (sechdrs[i].sh_offset > info->size)
234 goto truncated;
235 if (sechdrs[i].sh_type != SHT_SYMTAB)
236 continue;
238 info->symtab_start = (void *)hdr + sechdrs[i].sh_offset;
239 info->symtab_stop = (void *)hdr + sechdrs[i].sh_offset
240 + sechdrs[i].sh_size;
241 info->strtab = (void *)hdr +
242 sechdrs[sechdrs[i].sh_link].sh_offset;
244 if (!info->symtab_start) {
245 fprintf(stderr, "modpost: %s no symtab?\n", filename);
246 abort();
248 /* Fix endianness in symbols */
249 for (sym = info->symtab_start; sym < info->symtab_stop; sym++) {
250 sym->st_shndx = TO_NATIVE(sym->st_shndx);
251 sym->st_name = TO_NATIVE(sym->st_name);
252 sym->st_value = TO_NATIVE(sym->st_value);
253 sym->st_size = TO_NATIVE(sym->st_size);
255 return;
257 truncated:
258 fprintf(stderr, "modpost: %s is truncated.\n", filename);
259 abort();
262 void
263 parse_elf_finish(struct elf_info *info)
265 munmap(info->hdr, info->size);
268 #define CRC_PFX MODULE_SYMBOL_PREFIX "__crc_"
269 #define KSYMTAB_PFX MODULE_SYMBOL_PREFIX "__ksymtab_"
271 void
272 handle_modversions(struct module *mod, struct elf_info *info,
273 Elf_Sym *sym, const char *symname)
275 struct symbol *s;
276 unsigned int crc;
278 switch (sym->st_shndx) {
279 case SHN_COMMON:
280 fprintf(stderr, "*** Warning: \"%s\" [%s] is COMMON symbol\n",
281 symname, mod->name);
282 break;
283 case SHN_ABS:
284 /* CRC'd symbol */
285 if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) {
286 crc = (unsigned int) sym->st_value;
287 add_exported_symbol(symname + strlen(CRC_PFX),
288 mod, &crc);
289 modversions = 1;
291 break;
292 case SHN_UNDEF:
293 /* undefined symbol */
294 if (ELF_ST_BIND(sym->st_info) != STB_GLOBAL)
295 break;
296 /* ignore global offset table */
297 if (strcmp(symname, "_GLOBAL_OFFSET_TABLE_") == 0)
298 break;
299 if (info->hdr->e_machine == EM_SPARC ||
300 info->hdr->e_machine == EM_SPARCV9) {
301 /* Ignore register directives. */
302 if (ELF_ST_TYPE(sym->st_info) == STT_REGISTER)
303 break;
306 if (memcmp(symname, MODULE_SYMBOL_PREFIX,
307 strlen(MODULE_SYMBOL_PREFIX)) == 0) {
308 s = alloc_symbol(symname +
309 strlen(MODULE_SYMBOL_PREFIX));
310 /* add to list */
311 s->next = mod->unres;
312 mod->unres = s;
314 break;
315 default:
316 /* All exported symbols */
317 if (memcmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) {
318 add_exported_symbol(symname + strlen(KSYMTAB_PFX),
319 mod, NULL);
321 break;
325 void
326 read_symbols(char *modname)
328 const char *symname;
329 struct module *mod;
330 struct elf_info info = { };
331 struct symbol *s;
332 Elf_Sym *sym;
334 /* When there's no vmlinux, don't print warnings about
335 * unresolved symbols (since there'll be too many ;) */
336 if (strcmp(modname, "vmlinux") == 0)
337 have_vmlinux = 1;
339 parse_elf(&info, modname);
341 mod = new_module(modname);
343 for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
344 symname = info.strtab + sym->st_name;
346 handle_modversions(mod, &info, sym, symname);
347 handle_moddevtable(mod, &info, sym, symname);
349 parse_elf_finish(&info);
351 /* Our trick to get versioning for struct_module - it's
352 * never passed as an argument to an exported function, so
353 * the automatic versioning doesn't pick it up, but it's really
354 * important anyhow */
355 if (modversions) {
356 s = alloc_symbol("struct_module");
357 /* add to list */
358 s->next = mod->unres;
359 mod->unres = s;
363 #define SZ 500
365 /* We first write the generated file into memory using the
366 * following helper, then compare to the file on disk and
367 * only update the later if anything changed */
369 void __attribute__((format(printf, 2, 3)))
370 buf_printf(struct buffer *buf, const char *fmt, ...)
372 char tmp[SZ];
373 int len;
374 va_list ap;
376 va_start(ap, fmt);
377 len = vsnprintf(tmp, SZ, fmt, ap);
378 if (buf->size - buf->pos < len + 1) {
379 buf->size += 128;
380 buf->p = realloc(buf->p, buf->size);
382 strncpy(buf->p + buf->pos, tmp, len + 1);
383 buf->pos += len;
384 va_end(ap);
387 void
388 buf_write(struct buffer *buf, const char *s, int len)
390 if (buf->size - buf->pos < len) {
391 buf->size += len;
392 buf->p = realloc(buf->p, buf->size);
394 strncpy(buf->p + buf->pos, s, len);
395 buf->pos += len;
398 /* Header for the generated file */
400 void
401 add_header(struct buffer *b)
403 buf_printf(b, "#include <linux/module.h>\n");
404 buf_printf(b, "#include <linux/vermagic.h>\n");
405 buf_printf(b, "#include <linux/compiler.h>\n");
406 buf_printf(b, "\n");
407 buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n");
410 /* Record CRCs for unresolved symbols */
412 void
413 add_versions(struct buffer *b, struct module *mod)
415 struct symbol *s, *exp;
417 for (s = mod->unres; s; s = s->next) {
418 exp = find_symbol(s->name);
419 if (!exp || exp->module == mod) {
420 if (have_vmlinux)
421 fprintf(stderr, "*** Warning: \"%s\" [%s.ko] "
422 "undefined!\n", s->name, mod->name);
423 continue;
425 s->module = exp->module;
426 s->crc_valid = exp->crc_valid;
427 s->crc = exp->crc;
430 if (!modversions)
431 return;
433 buf_printf(b, "\n");
434 buf_printf(b, "static const struct modversion_info ____versions[]\n");
435 buf_printf(b, "__attribute__((section(\"__versions\"))) = {\n");
437 for (s = mod->unres; s; s = s->next) {
438 if (!s->module) {
439 continue;
441 if (!s->crc_valid) {
442 fprintf(stderr, "*** Warning: \"%s\" [%s.ko] "
443 "has no CRC!\n",
444 s->name, mod->name);
445 continue;
447 buf_printf(b, "\t{ %#8x, \"%s\" },\n", s->crc, s->name);
450 buf_printf(b, "};\n");
453 void
454 add_depends(struct buffer *b, struct module *mod, struct module *modules)
456 struct symbol *s;
457 struct module *m;
458 int first = 1;
460 for (m = modules; m; m = m->next) {
461 if (strcmp(m->name, "vmlinux") == 0)
462 m->seen = 1;
463 else
464 m->seen = 0;
467 buf_printf(b, "\n");
468 buf_printf(b, "static const char __module_depends[]\n");
469 buf_printf(b, "__attribute_used__\n");
470 buf_printf(b, "__attribute__((section(\".modinfo\"))) =\n");
471 buf_printf(b, "\"depends=");
472 for (s = mod->unres; s; s = s->next) {
473 if (!s->module)
474 continue;
476 if (s->module->seen)
477 continue;
479 s->module->seen = 1;
480 buf_printf(b, "%s%s", first ? "" : ",",
481 strrchr(s->module->name, '/') + 1);
482 first = 0;
484 buf_printf(b, "\";\n");
487 void
488 write_if_changed(struct buffer *b, const char *fname)
490 char *tmp;
491 FILE *file;
492 struct stat st;
494 file = fopen(fname, "r");
495 if (!file)
496 goto write;
498 if (fstat(fileno(file), &st) < 0)
499 goto close_write;
501 if (st.st_size != b->pos)
502 goto close_write;
504 tmp = NOFAIL(malloc(b->pos));
505 if (fread(tmp, 1, b->pos, file) != b->pos)
506 goto free_write;
508 if (memcmp(tmp, b->p, b->pos) != 0)
509 goto free_write;
511 free(tmp);
512 fclose(file);
513 return;
515 free_write:
516 free(tmp);
517 close_write:
518 fclose(file);
519 write:
520 file = fopen(fname, "w");
521 if (!file) {
522 perror(fname);
523 exit(1);
525 if (fwrite(b->p, 1, b->pos, file) != b->pos) {
526 perror(fname);
527 exit(1);
529 fclose(file);
533 main(int argc, char **argv)
535 struct module *mod;
536 struct buffer buf = { };
537 char fname[SZ];
539 for (; argv[1]; argv++) {
540 read_symbols(argv[1]);
543 for (mod = modules; mod; mod = mod->next) {
544 if (strcmp(mod->name, "vmlinux") == 0)
545 continue;
547 buf.pos = 0;
549 add_header(&buf);
550 add_versions(&buf, mod);
551 add_depends(&buf, mod, modules);
552 add_moddevtable(&buf, mod);
554 sprintf(fname, "%s.mod.c", mod->name);
555 write_if_changed(&buf, fname);
557 return 0;