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

📄 insmod.c

📁 为samsung2410 ARM移植的busybox工具包
💻 C
📖 第 1 页 / 共 5 页
字号:
						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 BB_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;	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_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, "__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, "__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 = obj_find_section(f, "__ksymtab");	if (sec && sec->header.sh_size) {		module->syms = sec->header.sh_addr;		module->nsyms = sec->header.sh_size / (2 * tgt_sizeof_char_p);	}	if (n_ext_modules_used) {		sec = obj_find_section(f, ".kmodtab");		module->deps = sec->header.sh_addr;		module->ndeps = n_ext_modules_used;	}	module->init =		obj_symbol_final_value(f, obj_find_symbol(f, "init_module"));	module->cleanup =		obj_symbol_final_value(f, obj_find_symbol(f, "cleanup_module"));	sec = obj_find_section(f, "__ex_table");	if (sec) {		module->ex_table_start = sec->header.sh_addr;		module->ex_table_end = sec->header.sh_addr + sec->header.sh_size;	}	sec = obj_find_section(f, ".text.init");	if (sec) {		module->runsize = sec->header.sh_addr - m_addr;	}	sec = obj_find_section(f, ".data.init");	if (sec) {		if (!module->runsize ||			module->runsize > sec->header.sh_addr - m_addr)				module->runsize = sec->header.sh_addr - m_addr;	}	sec = obj_find_section(f, ARCHDATA_SEC_NAME);	if (sec && sec->header.sh_size) {		module->archdata_start = (void*)sec->header.sh_addr;		module->archdata_end = module->archdata_start + sec->header.sh_size;	}	sec = obj_find_section(f, KALLSYMS_SEC_NAME);	if (sec && sec->header.sh_size) {		module->kallsyms_start = (void*)sec->header.sh_addr;		module->kallsyms_end = module->kallsyms_start + sec->header.sh_size;	}	if (!arch_init_module(f, module))		return 0;	/* 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);	ret = new_sys_init_module(m_name, (struct new_module *) image);	if (ret)		perror_msg("init_module: %s", m_name);	free(image);	return ret == 0;}#else#define new_init_module(x, y, z) TRUE#define new_create_this_module(x, y) 0#define new_create_module_ksymtab(x)#define query_module(v, w, x, y, z) -1#endif							/* BB_FEATURE_NEW_MODULE_INTERFACE *//*======================================================================*/static intobj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,				 const char *string){	struct obj_string_patch *p;	struct obj_section *strsec;	size_t len = strlen(string) + 1;	char *loc;	p = xmalloc(sizeof(*p));	p->next = f->string_patches;	p->reloc_secidx = secidx;	p->reloc_offset = offset;	f->string_patches = p;	strsec = obj_find_section(f, ".kstrtab");	if (strsec == NULL) {		strsec = obj_create_alloced_section(f, ".kstrtab", 1, len);		p->string_offset = 0;		loc = strsec->contents;	} else {		p->string_offset = strsec->header.sh_size;		loc = obj_extend_section(strsec, len);	}	memcpy(loc, string, len);	return 1;}static intobj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,				 struct obj_symbol *sym){	struct obj_symbol_patch *p;	p = xmalloc(sizeof(*p));	p->next = f->symbol_patches;	p->reloc_secidx = secidx;	p->reloc_offset = offset;	p->sym = sym;	f->symbol_patches = p;	return 1;}static int obj_check_undefineds(struct obj_file *f){	unsigned long i;	int ret = 1;	for (i = 0; i < HASH_BUCKETS; ++i) {		struct obj_symbol *sym;		for (sym = f->symtab[i]; sym; sym = sym->next)			if (sym->secidx == SHN_UNDEF) {				if (ELFW(ST_BIND) (sym->info) == STB_WEAK) {					sym->secidx = SHN_ABS;					sym->value = 0;				} else {					error_msg("unresolved symbol %s", sym->name);					ret = 0;				}			}	}	return ret;}static void obj_allocate_commons(struct obj_file *f){	struct common_entry {		struct common_entry *next;		struct obj_symbol *sym;	} *common_head = NULL;	unsigned long i;	for (i = 0; i < HASH_BUCKETS; ++i) {		struct obj_symbol *sym;		for (sym = f->symtab[i]; sym; sym = sym->next)			if (sym->secidx == SHN_COMMON) {				/* Collect all COMMON symbols and sort them by size so as to				   minimize space wasted by alignment requirements.  */				{					struct common_entry **p, *n;					for (p = &common_head; *p; p = &(*p)->next)						if (sym->size <= (*p)->sym->size)							break;					n = alloca(sizeof(*n));					n->next = *p;					n->sym = sym;					*p = n;				}			}	}	for (i = 1; i < f->local_symtab_size; ++i) {		struct obj_symbol *sym = f->local_symtab[i];		if (sym && sym->secidx == SHN_COMMON) {			struct common_entry **p, *n;			for (p = &common_head;

⌨️ 快捷键说明

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