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

📄 insmod.c

📁 这是一个SIGMA方案的PMP播放器的UCLINUX程序,可播放DVD,VCD,CD MP3...有很好的参考价值.
💻 C
📖 第 1 页 / 共 5 页
字号:
			for (i = 0; i < n_ext_modules; ++i)				if (ext_modules[i].used)					ref++->module = ext_modules[i].addr;		}	}	/* Fill in routines.  */	routines.init =		obj_symbol_final_value(f, obj_find_symbol(f, SPFX "init_module"));	routines.cleanup =		obj_symbol_final_value(f, obj_find_symbol(f, SPFX "cleanup_module"));	/* Whew!  All of the initialization is complete.  Collect the final	   module image and give it to the kernel.  */	image = xmalloc(m_size);	obj_create_image(f, image);	/* image holds the complete relocated module, accounting correctly for	   mod_use_count.  However the old module kernel support assume that	   it is receiving something which does not contain mod_use_count.  */	ret = old_sys_init_module(m_name, image + sizeof(long),							  m_size | (flag_autoclean ? OLD_MOD_AUTOCLEAN										: 0), &routines, symtab);	if (ret)		perror_msg("init_module: %s", m_name);	free(image);	free(symtab);	return ret == 0;}#else#define old_create_mod_use_count(x) TRUE#define old_init_module(x, y, z) TRUE#endif							/* CONFIG_FEATURE_OLD_MODULE_INTERFACE *//*======================================================================*//* Functions relating to module loading after 2.1.18.  */static intnew_process_module_arguments(struct obj_file *f, int argc, char **argv){	while (argc > 0) {		char *p, *q, *key, *sym_name;		struct obj_symbol *sym;		char *contents, *loc;		int min, max, n;		p = *argv;		if ((q = strchr(p, '=')) == NULL) {			argc--;			continue;                }		key = alloca(q - p + 6);		memcpy(key, "parm_", 5);		memcpy(key + 5, p, q - p);		key[q - p + 5] = 0;		p = get_modinfo_value(f, key);		key += 5;		if (p == NULL) {			error_msg("invalid parameter %s", key);			return 0;		}#ifdef SYMBOL_PREFIX		sym_name = alloca (strlen (key) + sizeof SYMBOL_PREFIX);		strcpy (sym_name, SYMBOL_PREFIX);		strcat (sym_name, key);#else		sym_name = key;#endif		sym = obj_find_symbol(f, sym_name);		/* Also check that the parameter was not resolved from the kernel.  */		if (sym == NULL || sym->secidx > SHN_HIRESERVE) {			error_msg("symbol for parameter %s not found", key);			return 0;		}		if (isdigit(*p)) {			min = strtoul(p, &p, 10);			if (*p == '-')				max = strtoul(p + 1, &p, 10);			else				max = min;		} else			min = max = 1;		contents = f->sections[sym->secidx]->contents;		loc = contents + sym->value;		n = (*++q != '\0');		while (1) {			if ((*p == 's') || (*p == 'c')) {				char *str;				/* Do C quoting if we begin with a ", else slurp the lot.  */				if (*q == '"') {					char *r;					str = alloca(strlen(q));					for (r = str, q++; *q != '"'; ++q, ++r) {						if (*q == '\0') {							error_msg("improperly terminated string argument for %s",									key);							return 0;						} else if (*q == '\\')							switch (*++q) {							case 'a':								*r = '\a';								break;							case 'b':								*r = '\b';								break;							case 'e':								*r = '\033';								break;							case 'f':								*r = '\f';								break;							case 'n':								*r = '\n';								break;							case 'r':								*r = '\r';								break;							case 't':								*r = '\t';								break;							case '0':							case '1':							case '2':							case '3':							case '4':							case '5':							case '6':							case '7':								{									int c = *q - '0';									if (q[1] >= '0' && q[1] <= '7') {										c = (c * 8) + *++q - '0';										if (q[1] >= '0' && q[1] <= '7')											c = (c * 8) + *++q - '0';									}									*r = c;								}								break;							default:								*r = *q;								break;						} else							*r = *q;					}					*r = '\0';					++q;				} else {					char *r;					/* In this case, the string is not quoted. We will break					   it using the coma (like for ints). If the user wants to					   include comas in a string, he just has to quote it */					/* Search the next coma */					r = strchr(q, ',');					/* Found ? */					if (r != (char *) NULL) {						/* Recopy the current field */						str = alloca(r - q + 1);						memcpy(str, q, r - q);						/* I don't know if it is usefull, as the previous case						   doesn't null terminate the string ??? */						str[r - q] = '\0';						/* Keep next fields */						q = r;					} else {						/* last string */						str = q;						q = "";					}				}				if (*p == 's') {					/* Normal string */					obj_string_patch(f, sym->secidx, loc - contents, str);					loc += tgt_sizeof_char_p;				} else {					/* Array of chars (in fact, matrix !) */					unsigned long charssize;	/* size of each member */					/* Get the size of each member */					/* Probably we should do that outside the loop ? */					if (!isdigit(*(p + 1))) {						error_msg("parameter type 'c' for %s must be followed by"								" the maximum size", key);						return 0;					}					charssize = strtoul(p + 1, (char **) NULL, 10);					/* Check length */					if (strlen(str) >= charssize) {						error_msg("string too long for %s (max %ld)", key,								charssize - 1);						return 0;					}					/* Copy to location */					strcpy((char *) loc, str);					loc += charssize;				}			} else {				long v = strtoul(q, &q, 0);				switch (*p) {				case 'b':					*loc++ = v;					break;				case 'h':					*(short *) loc = v;					loc += tgt_sizeof_short;					break;				case 'i':					*(int *) loc = v;					loc += tgt_sizeof_int;					break;				case 'l':					*(long *) loc = v;					loc += tgt_sizeof_long;					break;				default:					error_msg("unknown parameter type '%c' for %s", *p, key);					return 0;				}			}		  retry_end_of_value:			switch (*q) {			case '\0':				goto end_of_arg;			case ' ':			case '\t':			case '\n':			case '\r':				++q;				goto retry_end_of_value;			case ',':				if (++n > max) {					error_msg("too many values for %s (max %d)", key, max);					return 0;				}				++q;				break;			default:				error_msg("invalid argument syntax for %s", key);				return 0;			}		}	  end_of_arg:		if (n < min) {			error_msg("too few values for %s (min %d)", key, min);			return 0;		}		argc--, argv++;	}	return 1;}#ifdef CONFIG_FEATURE_INSMOD_VERSION_CHECKINGstatic int new_is_module_checksummed(struct obj_file *f){	const char *p = get_modinfo_value(f, "using_checksums");	if (p)		return atoi(p);	else		return 0;}/* Get the module's kernel version in the canonical integer form.  */static intnew_get_module_version(struct obj_file *f, char str[STRVERSIONLEN]){	char *p, *q;	int a, b, c;	p = get_modinfo_value(f, "kernel_version");	if (p == NULL)		return -1;	safe_strncpy(str, p, STRVERSIONLEN);	a = strtoul(p, &p, 10);	if (*p != '.')		return -1;	b = strtoul(p + 1, &p, 10);	if (*p != '.')		return -1;	c = strtoul(p + 1, &q, 10);	if (p + 1 == q)		return -1;	return a << 16 | b << 8 | c;}#endif   /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */#ifdef CONFIG_FEATURE_NEW_MODULE_INTERFACE/* Fetch the loaded modules, and all currently exported symbols.  */static int new_get_kernel_symbols(void){	char *module_names, *mn;	struct external_module *modules, *m;	struct new_module_symbol *syms, *s;	size_t ret, bufsize, nmod, nsyms, i, j;	/* Collect the loaded modules.  */	module_names = xmalloc(bufsize = 256);  retry_modules_load:	if (query_module(NULL, QM_MODULES, module_names, bufsize, &ret)) {		if (errno == ENOSPC && bufsize < ret) {			module_names = xrealloc(module_names, bufsize = ret);			goto retry_modules_load;		}		perror_msg("QM_MODULES");		return 0;	}	n_ext_modules = nmod = ret;	/* Collect the modules' symbols.  */	if (nmod){		ext_modules = modules = xmalloc(nmod * sizeof(*modules));		memset(modules, 0, nmod * sizeof(*modules));		for (i = 0, mn = module_names, m = modules;			 i < nmod; ++i, ++m, mn += strlen(mn) + 1) {			struct new_module_info info;				if (query_module(mn, QM_INFO, &info, sizeof(info), &ret)) {				if (errno == ENOENT) {					/* The module was removed out from underneath us.  */					continue;				}				perror_msg("query_module: QM_INFO: %s", mn);				return 0;			}				syms = xmalloc(bufsize = 1024);		  retry_mod_sym_load:			if (query_module(mn, QM_SYMBOLS, syms, bufsize, &ret)) {				switch (errno) {				case ENOSPC:					syms = xrealloc(syms, bufsize = ret);					goto retry_mod_sym_load;				case ENOENT:					/* The module was removed out from underneath us.  */					continue;				default:					perror_msg("query_module: QM_SYMBOLS: %s", mn);					return 0;				}			}			nsyms = ret;				m->name = mn;			m->addr = info.addr;			m->nsyms = nsyms;			m->syms = syms;				for (j = 0, s = syms; j < nsyms; ++j, ++s) {				s->name += (unsigned long) syms;			}		}	}	/* Collect the kernel's symbols.  */	syms = xmalloc(bufsize = 16 * 1024);  retry_kern_sym_load:	if (query_module(NULL, QM_SYMBOLS, syms, bufsize, &ret)) {		if (errno == ENOSPC && bufsize < ret) {			syms = xrealloc(syms, bufsize = ret);			goto retry_kern_sym_load;		}		perror_msg("kernel: QM_SYMBOLS");		return 0;	}	nksyms = nsyms = ret;	ksyms = syms;	for (j = 0, s = syms; j < nsyms; ++j, ++s) {		s->name += (unsigned long) syms;	}	return 1;}/* Return the kernel symbol checksum version, or zero if not used.  */static int new_is_kernel_checksummed(void){	struct new_module_symbol *s;	size_t i;	/* Using_Versions is not the first symbol, but it should be in there.  */	for (i = 0, s = ksyms; i < nksyms; ++i, ++s)		if (strcmp((char *) s->name, "Using_Versions") == 0)			return s->value;	return 0;}static int new_create_this_module(struct obj_file *f, const char *m_name){	struct obj_section *sec;	sec = obj_create_alloced_section_first(f, ".this", tgt_sizeof_long,										   sizeof(struct new_module));	memset(sec->contents, 0, sizeof(struct new_module));	obj_add_symbol(f, SPFX "__this_module", -1,		       ELFW(ST_INFO) (STB_LOCAL, STT_OBJECT), sec->idx, 0,		       sizeof(struct new_module));	obj_string_patch(f, sec->idx, offsetof(struct new_module, name),					 m_name);	return 1;}static int new_create_module_ksymtab(struct obj_file *f){	struct obj_section *sec;	int i;	/* We must always add the module references.  */	if (n_ext_modules_used) {		struct new_module_ref *dep;		struct obj_symbol *tm;		sec = obj_create_alloced_section(f, ".kmodtab", tgt_sizeof_void_p,										 (sizeof(struct new_module_ref)										  * n_ext_modules_used));		if (!sec)			return 0;		tm = obj_find_symbol(f, SPFX "__this_module");		dep = (struct new_module_ref *) sec->contents;		for (i = 0; i < n_ext_modules; ++i)			if (ext_modules[i].used) {				dep->dep = ext_modules[i].addr;				obj_symbol_patch(f, sec->idx,								 (char *) &dep->ref - sec->contents, tm);				dep->next_ref = 0;				++dep;			}	}	if (flag_export && !obj_find_section(f, "__ksymtab")) {		size_t nsyms;		int *loaded;		sec =			obj_create_alloced_section(f, "__ksymtab", tgt_sizeof_void_p,									   0);		/* We don't want to export symbols residing in sections that		   aren't loaded.  There are a number of these created so that		   we make sure certain module options don't appear twice.  */		loaded = alloca(sizeof(int) * (i = f->header.e_shnum));		while (--i >= 0)			loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0;		for (nsyms = i = 0; i < HASH_BUCKETS; ++i) {			struct obj_symbol *sym;			for (sym = f->symtab[i]; sym; sym = sym->next)				if (ELFW(ST_BIND) (sym->info) != STB_LOCAL					&& sym->secidx <= SHN_HIRESERVE					&& (sym->secidx >= SHN_LORESERVE						|| loaded[sym->secidx])) {					ElfW(Addr) ofs = nsyms * 2 * tgt_sizeof_void_p;					obj_symbol_patch(f, sec->idx, ofs, sym);					obj_string_patch(f, sec->idx, ofs + tgt_sizeof_void_p,									 sym->name);					nsyms++;				}		}		obj_extend_section(sec, nsyms * 2 * tgt_sizeof_char_p);	}	return 1;}static intnew_init_module(const char *m_name, struct obj_file *f,				unsigned long m_size){	struct new_module *module;	struct obj_section *sec;	void *image;	int ret;	tgt_long m_addr;	sec = obj_find_section(f, ".this");	if (!sec || !sec->contents) { 		perror_msg_and_die("corrupt module %s?",m_name);	}	module = (struct new_module *) sec->contents;	m_addr = sec->header.sh_addr;	module->size_of_struct = sizeof(*module);	module->size = m_size;	module->flags = flag_autoclean ? NEW_MOD_AUTOCLEAN : 0;	sec = 

⌨️ 快捷键说明

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