⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 modpost.c

📁 Linux Kernel 2.6.9 for OMAP1710
💻 C
📖 第 1 页 / 共 2 页
字号:
						  strlen(MODULE_SYMBOL_PREFIX),						  mod->unres);		break;	default:		/* All exported symbols */		if (memcmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) {			add_exported_symbol(symname + strlen(KSYMTAB_PFX),					    mod, NULL);		}		if (strcmp(symname, MODULE_SYMBOL_PREFIX "init_module") == 0)			mod->has_init = 1;		if (strcmp(symname, MODULE_SYMBOL_PREFIX "cleanup_module") == 0)			mod->has_cleanup = 1;		break;	}}intis_vmlinux(const char *modname){	const char *myname;	if ((myname = strrchr(modname, '/')))		myname++;	else		myname = modname;	return strcmp(myname, "vmlinux") == 0;}voidread_symbols(char *modname){	const char *symname;	struct module *mod;	struct elf_info info = { };	Elf_Sym *sym;	parse_elf(&info, modname);	mod = new_module(modname);	/* When there's no vmlinux, don't print warnings about	 * unresolved symbols (since there'll be too many ;) */	if (is_vmlinux(modname)) {		unsigned int fake_crc = 0;		have_vmlinux = 1;		add_exported_symbol("struct_module", mod, &fake_crc);		mod->skip = 1;	}	for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {		symname = info.strtab + sym->st_name;		handle_modversions(mod, &info, sym, symname);		handle_moddevtable(mod, &info, sym, symname);	}	maybe_frob_version(modname, info.modinfo, info.modinfo_len,			   (void *)info.modinfo - (void *)info.hdr);	parse_elf_finish(&info);	/* Our trick to get versioning for struct_module - it's	 * never passed as an argument to an exported function, so	 * the automatic versioning doesn't pick it up, but it's really	 * important anyhow */	if (modversions)		mod->unres = alloc_symbol("struct_module", mod->unres);}#define SZ 500/* We first write the generated file into memory using the * following helper, then compare to the file on disk and * only update the later if anything changed */void __attribute__((format(printf, 2, 3)))buf_printf(struct buffer *buf, const char *fmt, ...){	char tmp[SZ];	int len;	va_list ap;		va_start(ap, fmt);	len = vsnprintf(tmp, SZ, fmt, ap);	if (buf->size - buf->pos < len + 1) {		buf->size += 128;		buf->p = realloc(buf->p, buf->size);	}	strncpy(buf->p + buf->pos, tmp, len + 1);	buf->pos += len;	va_end(ap);}voidbuf_write(struct buffer *buf, const char *s, int len){	if (buf->size - buf->pos < len) {		buf->size += len;		buf->p = realloc(buf->p, buf->size);	}	strncpy(buf->p + buf->pos, s, len);	buf->pos += len;}/* Header for the generated file */voidadd_header(struct buffer *b, struct module *mod){	buf_printf(b, "#include <linux/module.h>\n");	buf_printf(b, "#include <linux/vermagic.h>\n");	buf_printf(b, "#include <linux/compiler.h>\n");	buf_printf(b, "\n");	buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n");	buf_printf(b, "\n");	buf_printf(b, "#undef unix\n"); /* We have a module called "unix" */	buf_printf(b, "struct module __this_module\n");	buf_printf(b, "__attribute__((section(\".gnu.linkonce.this_module\"))) = {\n");	buf_printf(b, " .name = __stringify(KBUILD_MODNAME),\n");	if (mod->has_init)		buf_printf(b, " .init = init_module,\n");	if (mod->has_cleanup)		buf_printf(b, "#ifdef CONFIG_MODULE_UNLOAD\n"			      " .exit = cleanup_module,\n"			      "#endif\n");	buf_printf(b, "};\n");}/* Record CRCs for unresolved symbols */voidadd_versions(struct buffer *b, struct module *mod){	struct symbol *s, *exp;	for (s = mod->unres; s; s = s->next) {		exp = find_symbol(s->name);		if (!exp || exp->module == mod) {			if (have_vmlinux)				fprintf(stderr, "*** Warning: \"%s\" [%s.ko] "				"undefined!\n",	s->name, mod->name);			continue;		}		s->module = exp->module;		s->crc_valid = exp->crc_valid;		s->crc = exp->crc;	}	if (!modversions)		return;	buf_printf(b, "\n");	buf_printf(b, "static const struct modversion_info ____versions[]\n");	buf_printf(b, "__attribute_used__\n");	buf_printf(b, "__attribute__((section(\"__versions\"))) = {\n");	for (s = mod->unres; s; s = s->next) {		if (!s->module) {			continue;		}		if (!s->crc_valid) {			fprintf(stderr, "*** Warning: \"%s\" [%s.ko] "				"has no CRC!\n",				s->name, mod->name);			continue;		}		buf_printf(b, "\t{ %#8x, \"%s\" },\n", s->crc, s->name);	}	buf_printf(b, "};\n");}voidadd_depends(struct buffer *b, struct module *mod, struct module *modules){	struct symbol *s;	struct module *m;	int first = 1;	for (m = modules; m; m = m->next) {		m->seen = is_vmlinux(m->name);	}	buf_printf(b, "\n");	buf_printf(b, "static const char __module_depends[]\n");	buf_printf(b, "__attribute_used__\n");	buf_printf(b, "__attribute__((section(\".modinfo\"))) =\n");	buf_printf(b, "\"depends=");	for (s = mod->unres; s; s = s->next) {		if (!s->module)			continue;		if (s->module->seen)			continue;		s->module->seen = 1;		buf_printf(b, "%s%s", first ? "" : ",",			   strrchr(s->module->name, '/') + 1);		first = 0;	}	buf_printf(b, "\";\n");}voidwrite_if_changed(struct buffer *b, const char *fname){	char *tmp;	FILE *file;	struct stat st;	file = fopen(fname, "r");	if (!file)		goto write;	if (fstat(fileno(file), &st) < 0)		goto close_write;	if (st.st_size != b->pos)		goto close_write;	tmp = NOFAIL(malloc(b->pos));	if (fread(tmp, 1, b->pos, file) != b->pos)		goto free_write;	if (memcmp(tmp, b->p, b->pos) != 0)		goto free_write;	free(tmp);	fclose(file);	return; free_write:	free(tmp); close_write:	fclose(file); write:	file = fopen(fname, "w");	if (!file) {		perror(fname);		exit(1);	}	if (fwrite(b->p, 1, b->pos, file) != b->pos) {		perror(fname);		exit(1);	}	fclose(file);}voidread_dump(const char *fname){	unsigned long size, pos = 0;	void *file = grab_file(fname, &size);	char *line;        if (!file)		/* No symbol versions, silently ignore */		return;	while ((line = get_next_line(&pos, file, size))) {		char *symname, *modname, *d;		unsigned int crc;		struct module *mod;		if (!(symname = strchr(line, '\t')))			goto fail;		*symname++ = '\0';		if (!(modname = strchr(symname, '\t')))			goto fail;		*modname++ = '\0';		if (strchr(modname, '\t'))			goto fail;		crc = strtoul(line, &d, 16);		if (*symname == '\0' || *modname == '\0' || *d != '\0')			goto fail;		if (!(mod = find_module(modname))) {			if (is_vmlinux(modname)) {				have_vmlinux = 1;			}			mod = new_module(NOFAIL(strdup(modname)));			mod->skip = 1;		}		add_exported_symbol(symname, mod, &crc);	}	return;fail:	fatal("parse error in symbol dump file\n");}voidwrite_dump(const char *fname){	struct buffer buf = { };	struct symbol *symbol;	int n;	for (n = 0; n < SYMBOL_HASH_SIZE ; n++) {		symbol = symbolhash[n];		while (symbol) {			symbol = symbol->next;		}	}	for (n = 0; n < SYMBOL_HASH_SIZE ; n++) {		symbol = symbolhash[n];		while (symbol) {			buf_printf(&buf, "0x%08x\t%s\t%s\n", symbol->crc,				symbol->name, symbol->module->name);			symbol = symbol->next;		}	}	write_if_changed(&buf, fname);}intmain(int argc, char **argv){	struct module *mod;	struct buffer buf = { };	char fname[SZ];	char *dump_read = NULL, *dump_write = NULL;	int opt;	while ((opt = getopt(argc, argv, "i:mo:")) != -1) {		switch(opt) {			case 'i':				dump_read = optarg;				break;			case 'm':				modversions = 1;				break;			case 'o':				dump_write = optarg;				break;			default:				exit(1);		}	}	if (dump_read)		read_dump(dump_read);	while (optind < argc) {		read_symbols(argv[optind++]);	}	for (mod = modules; mod; mod = mod->next) {		if (mod->skip)			continue;		buf.pos = 0;		add_header(&buf, mod);		add_versions(&buf, mod);		add_depends(&buf, mod, modules);		add_moddevtable(&buf, mod);		sprintf(fname, "%s.mod.c", mod->name);		write_if_changed(&buf, fname);	}	if (dump_write)		write_dump(dump_write);	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -