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

📄 insmod.c

📁 为samsung2410 ARM移植的busybox工具包
💻 C
📖 第 1 页 / 共 5 页
字号:
{	struct external_module *m;	int i, nused = 0;	/* Add module symbols first.  */	for (i = 0, m = ext_modules; i < n_ext_modules; ++i, ++m)		if (m->nsyms			&& add_symbols_from(f, SHN_HIRESERVE + 2 + i, m->syms,								m->nsyms)) m->used = 1, ++nused;	n_ext_modules_used = nused;	/* And finally the symbols from the kernel proper.  */	if (nksyms)		add_symbols_from(f, SHN_HIRESERVE + 1, ksyms, nksyms);}static char *get_modinfo_value(struct obj_file *f, const char *key){	struct obj_section *sec;	char *p, *v, *n, *ep;	size_t klen = strlen(key);	sec = obj_find_section(f, ".modinfo");	if (sec == NULL)		return NULL;	p = sec->contents;	ep = p + sec->header.sh_size;	while (p < ep) {		v = strchr(p, '=');		n = strchr(p, '\0');		if (v) {			if (p + klen == v && strncmp(p, key, klen) == 0)				return v + 1;		} else {			if (p + klen == n && strcmp(p, key) == 0)				return n;		}		p = n + 1;	}	return NULL;}/*======================================================================*//* Functions relating to module loading in pre 2.1 kernels.  */static intold_process_module_arguments(struct obj_file *f, int argc, char **argv){	while (argc > 0) {		char *p, *q;		struct obj_symbol *sym;		int *loc;		p = *argv;		if ((q = strchr(p, '=')) == NULL) {			argc--;			continue;                }		*q++ = '\0';		sym = obj_find_symbol(f, p);		/* 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", p);			return 0;		}		loc = (int *) (f->sections[sym->secidx]->contents + sym->value);		/* Do C quoting if we begin with a ".  */		if (*q == '"') {			char *r, *str;			str = alloca(strlen(q));			for (r = str, q++; *q != '"'; ++q, ++r) {				if (*q == '\0') {					error_msg("improperly terminated string argument for %s", p);					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';			obj_string_patch(f, sym->secidx, sym->value, str);		} else if (*q >= '0' && *q <= '9') {			do				*loc++ = strtoul(q, &q, 0);			while (*q++ == ',');		} else {			char *contents = f->sections[sym->secidx]->contents;			char *myloc = contents + sym->value;			char *r;			/* To search for commas */			/* Break the string with comas */			while ((r = strchr(q, ',')) != (char *) NULL) {				*r++ = '\0';				obj_string_patch(f, sym->secidx, myloc - contents, q);				myloc += sizeof(char *);				q = r;			}			/* last part */			obj_string_patch(f, sym->secidx, myloc - contents, q);		}		argc--, argv++;	}	return 1;}#ifdef BB_FEATURE_INSMOD_VERSION_CHECKINGstatic int old_is_module_checksummed(struct obj_file *f){	return obj_find_symbol(f, "Using_Versions") != NULL;}/* Get the module's kernel version in the canonical integer form.  */static intold_get_module_version(struct obj_file *f, char str[STRVERSIONLEN]){	struct obj_symbol *sym;	char *p, *q;	int a, b, c;	sym = obj_find_symbol(f, "kernel_version");	if (sym == NULL)		return -1;	p = f->sections[sym->secidx]->contents + sym->value;	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   /* BB_FEATURE_INSMOD_VERSION_CHECKING */#ifdef BB_FEATURE_OLD_MODULE_INTERFACE/* Fetch all the symbols and divvy them up as appropriate for the modules.  */static int old_get_kernel_symbols(const char *m_name){	struct old_kernel_sym *ks, *k;	struct new_module_symbol *s;	struct external_module *mod;	int nks, nms, nmod, i;	nks = get_kernel_syms(NULL);	if (nks <= 0) {		if (nks)			perror_msg("get_kernel_syms: %s", m_name);		else			error_msg("No kernel symbols");		return 0;	}	ks = k = xmalloc(nks * sizeof(*ks));	if (get_kernel_syms(ks) != nks) {		perror("inconsistency with get_kernel_syms -- is someone else "			   "playing with modules?");		free(ks);		return 0;	}	/* Collect the module information.  */	mod = NULL;	nmod = -1;	while (k->name[0] == '#' && k->name[1]) {		struct old_kernel_sym *k2;		/* Find out how many symbols this module has.  */		for (k2 = k + 1; k2->name[0] != '#'; ++k2)			continue;		nms = k2 - k - 1;		mod = xrealloc(mod, (++nmod + 1) * sizeof(*mod));		mod[nmod].name = k->name + 1;		mod[nmod].addr = k->value;		mod[nmod].used = 0;		mod[nmod].nsyms = nms;		mod[nmod].syms = s = (nms ? xmalloc(nms * sizeof(*s)) : NULL);		for (i = 0, ++k; i < nms; ++i, ++s, ++k) {			s->name = (unsigned long) k->name;			s->value = k->value;		}		k = k2;	}	ext_modules = mod;	n_ext_modules = nmod + 1;	/* Now collect the symbols for the kernel proper.  */	if (k->name[0] == '#')		++k;	nksyms = nms = nks - (k - ks);	ksyms = s = (nms ? xmalloc(nms * sizeof(*s)) : NULL);	for (i = 0; i < nms; ++i, ++s, ++k) {		s->name = (unsigned long) k->name;		s->value = k->value;	}	return 1;}/* Return the kernel symbol checksum version, or zero if not used.  */static int old_is_kernel_checksummed(void){	/* Using_Versions is the first symbol.  */	if (nksyms > 0		&& strcmp((char *) ksyms[0].name,				  "Using_Versions") == 0) return ksyms[0].value;	else		return 0;}static int old_create_mod_use_count(struct obj_file *f){	struct obj_section *sec;	sec = obj_create_alloced_section_first(f, ".moduse", sizeof(long),										   sizeof(long));	obj_add_symbol(f, "mod_use_count_", -1,				   ELFW(ST_INFO) (STB_LOCAL, STT_OBJECT), sec->idx, 0,				   sizeof(long));	return 1;}static intold_init_module(const char *m_name, struct obj_file *f,				unsigned long m_size){	char *image;	struct old_mod_routines routines;	struct old_symbol_table *symtab;	int ret;	/* Create the symbol table */	{		int nsyms = 0, strsize = 0, total;		/* Size things first... */		if (flag_export) {			int i;			for (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->ksymidx = nsyms++;						strsize += strlen(sym->name) + 1;					}			}		}		total = (sizeof(struct old_symbol_table)				 + nsyms * sizeof(struct old_module_symbol)				 + n_ext_modules_used * sizeof(struct old_module_ref)				 + strsize);		symtab = xmalloc(total);		symtab->size = total;		symtab->n_symbols = nsyms;		symtab->n_refs = n_ext_modules_used;		if (flag_export && nsyms) {			struct old_module_symbol *ksym;			char *str;			int i;			ksym = symtab->symbol;			str = ((char *) ksym + nsyms * sizeof(struct old_module_symbol)				   + n_ext_modules_used * sizeof(struct old_module_ref));			for (i = 0; i < HASH_BUCKETS; ++i) {				struct obj_symbol *sym;				for (sym = f->symtab[i]; sym; sym = sym->next)					if (sym->ksymidx >= 0) {						ksym->addr = obj_symbol_final_value(f, sym);						ksym->name =							(unsigned long) str - (unsigned long) symtab;						strcpy(str, sym->name);						str += strlen(sym->name) + 1;						ksym++;					}			}		}		if (n_ext_modules_used) {			struct old_module_ref *ref;			int i;			ref = (struct old_module_ref *)				((char *) symtab->symbol + nsyms * sizeof(struct old_module_symbol));			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, "init_module"));	routines.cleanup =		obj_symbol_final_value(f, obj_find_symbol(f, "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							/* BB_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;		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;		}		sym = obj_find_symbol(f, key);		/* 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 */

⌨️ 快捷键说明

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