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

📄 insmod.c

📁 这是一个SIGMA方案的PMP播放器的UCLINUX程序,可播放DVD,VCD,CD MP3...有很好的参考价值.
💻 C
📖 第 1 页 / 共 5 页
字号:
	if (sym) {		if (sym->secidx >= SHN_LORESERVE)			return sym->value;		return sym->value + f->sections[sym->secidx]->header.sh_addr;	} else {		/* As a special case, a NULL sym has value zero.  */		return 0;	}}static struct obj_section *obj_find_section(struct obj_file *f, const char *name){	int i, n = f->header.e_shnum;	for (i = 0; i < n; ++i)		if (strcmp(f->sections[i]->name, name) == 0)			return f->sections[i];	return NULL;}static int obj_load_order_prio(struct obj_section *a){	unsigned long af, ac;	af = a->header.sh_flags;	ac = 0;	if (a->name[0] != '.' || strlen(a->name) != 10 ||		strcmp(a->name + 5, ".init"))		ac |= 32;	if (af & SHF_ALLOC)		ac |= 16;	if (!(af & SHF_WRITE))		ac |= 8;	if (af & SHF_EXECINSTR)		ac |= 4;	if (a->header.sh_type != SHT_NOBITS)		ac |= 2;	return ac;}static voidobj_insert_section_load_order(struct obj_file *f, struct obj_section *sec){	struct obj_section **p;	int prio = obj_load_order_prio(sec);	for (p = f->load_order_search_start; *p; p = &(*p)->load_next)		if (obj_load_order_prio(*p) < prio)			break;	sec->load_next = *p;	*p = sec;}static struct obj_section *obj_create_alloced_section(struct obj_file *f,											   const char *name,											   unsigned long align,											   unsigned long size){	int newidx = f->header.e_shnum++;	struct obj_section *sec;	f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec));	f->sections[newidx] = sec = arch_new_section();	memset(sec, 0, sizeof(*sec));	sec->header.sh_type = SHT_PROGBITS;	sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;	sec->header.sh_size = size;	sec->header.sh_addralign = align;	sec->name = name;	sec->idx = newidx;	if (size)		sec->contents = xmalloc(size);	obj_insert_section_load_order(f, sec);	return sec;}static struct obj_section *obj_create_alloced_section_first(struct obj_file *f,													 const char *name,													 unsigned long align,													 unsigned long size){	int newidx = f->header.e_shnum++;	struct obj_section *sec;	f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec));	f->sections[newidx] = sec = arch_new_section();	memset(sec, 0, sizeof(*sec));	sec->header.sh_type = SHT_PROGBITS;	sec->header.sh_flags = SHF_WRITE | SHF_ALLOC;	sec->header.sh_size = size;	sec->header.sh_addralign = align;	sec->name = name;	sec->idx = newidx;	if (size)		sec->contents = xmalloc(size);	sec->load_next = f->load_order;	f->load_order = sec;	if (f->load_order_search_start == &f->load_order)		f->load_order_search_start = &sec->load_next;	return sec;}static void *obj_extend_section(struct obj_section *sec, unsigned long more){	unsigned long oldsize = sec->header.sh_size;	if (more) { 		sec->contents = xrealloc(sec->contents, sec->header.sh_size += more);	}	return sec->contents + oldsize;}/* Conditionally add the symbols from the given symbol set to the   new module.  */static intadd_symbols_from(				 struct obj_file *f,				 int idx, struct new_module_symbol *syms, size_t nsyms){	struct new_module_symbol *s;	size_t i;	int used = 0;#ifdef SYMBOL_PREFIX	char *name_buf = 0;	size_t name_alloced_size = 0;#endif	for (i = 0, s = syms; i < nsyms; ++i, ++s) {		/* Only add symbols that are already marked external.		   If we override locals we may cause problems for		   argument initialization.  We will also create a false		   dependency on the module.  */		struct obj_symbol *sym;		char *name = (char *)s->name;#ifdef SYMBOL_PREFIX		/* Prepend SYMBOL_PREFIX to the symbol's name (the		   kernel exports `C names', but module object files		   reference `linker names').  */		size_t extra = sizeof SYMBOL_PREFIX;		size_t name_size = strlen (name) + extra;		if (name_size > name_alloced_size) {			name_alloced_size = name_size * 2;			name_buf = alloca (name_alloced_size);		}		strcpy (name_buf, SYMBOL_PREFIX);		strcpy (name_buf + extra - 1, name);		name = name_buf;#endif /* SYMBOL_PREFIX */		sym = obj_find_symbol(f, name);		if (sym && !(ELFW(ST_BIND) (sym->info) == STB_LOCAL)) {#ifdef SYMBOL_PREFIX			/* Put NAME_BUF into more permanent storage.  */			name = xmalloc (name_size);			strcpy (name, name_buf);#endif			sym = obj_add_symbol(f, name, -1,					     ELFW(ST_INFO) (STB_GLOBAL,							    STT_NOTYPE),					     idx, s->value, 0);			/* Did our symbol just get installed?  If so, mark the			   module as "used".  */			if (sym->secidx == idx)				used = 1;		}	}	return used;}static void add_kernel_symbols(struct obj_file *f){	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 CONFIG_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;	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_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));

⌨️ 快捷键说明

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