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

📄 insmod.c

📁 这是一个SIGMA方案的PMP播放器的UCLINUX程序,可播放DVD,VCD,CD MP3...有很好的参考价值.
💻 C
📖 第 1 页 / 共 5 页
字号:
struct obj_symbol_patch{  struct obj_symbol_patch *next;  int reloc_secidx;  ElfW(Addr) reloc_offset;  struct obj_symbol *sym;};/* Generic object manipulation routines.  */static unsigned long obj_elf_hash(const char *);static unsigned long obj_elf_hash_n(const char *, unsigned long len);static struct obj_symbol *obj_find_symbol (struct obj_file *f,					 const char *name);static ElfW(Addr) obj_symbol_final_value(struct obj_file *f,				  struct obj_symbol *sym);#ifdef CONFIG_FEATURE_INSMOD_VERSION_CHECKINGstatic void obj_set_symbol_compare(struct obj_file *f,			    int (*cmp)(const char *, const char *),			    unsigned long (*hash)(const char *));#endifstatic struct obj_section *obj_find_section (struct obj_file *f,					   const char *name);static void obj_insert_section_load_order (struct obj_file *f,				    struct obj_section *sec);static struct obj_section *obj_create_alloced_section (struct obj_file *f,						const char *name,						unsigned long align,						unsigned long size);static struct obj_section *obj_create_alloced_section_first (struct obj_file *f,						      const char *name,						      unsigned long align,						      unsigned long size);static void *obj_extend_section (struct obj_section *sec, unsigned long more);static int obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,		     const char *string);#ifdef CONFIG_FEATURE_NEW_MODULE_INTERFACEstatic int obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset,		     struct obj_symbol *sym);#endifstatic int obj_check_undefineds(struct obj_file *f);static void obj_allocate_commons(struct obj_file *f);static unsigned long obj_load_size (struct obj_file *f);static int obj_relocate (struct obj_file *f, ElfW(Addr) base);static struct obj_file *obj_load(FILE *f, int loadprogbits);static int obj_create_image (struct obj_file *f, char *image);/* Architecture specific manipulation routines.  */static struct obj_file *arch_new_file (void);static struct obj_section *arch_new_section (void);static struct obj_symbol *arch_new_symbol (void);static enum obj_reloc arch_apply_relocation (struct obj_file *f,				      struct obj_section *targsec,				      struct obj_section *symsec,				      struct obj_symbol *sym,				      ElfW(RelM) *rel, ElfW(Addr) value);static void arch_create_got (struct obj_file *f);#ifdef CONFIG_FEATURE_NEW_MODULE_INTERFACEstatic int arch_init_module (struct obj_file *f, struct new_module *);#endif#endif /* obj.h *///----------------------------------------------------------------------------//--------end of modutils obj.h//----------------------------------------------------------------------------/* SPFX is always a string, so it can be concatenated to string constants.  */#ifdef SYMBOL_PREFIX#define SPFX	SYMBOL_PREFIX#else#define SPFX 	""#endif#define _PATH_MODULES	"/lib/modules"static const int STRVERSIONLEN = 32;/*======================================================================*/static int flag_force_load = 0;static int flag_autoclean = 0;static int flag_verbose = 0;static int flag_quiet = 0;static int flag_export = 1;/*======================================================================*/#if defined(CONFIG_USE_LIST)struct arch_list_entry{	struct arch_list_entry *next;	CONFIG_LIST_ARCHTYPE addend;	int offset;	int inited : 1;};#endif#if defined(CONFIG_USE_SINGLE)struct arch_single_entry{	int offset;	int inited : 1;	int allocated : 1;};#endif#if defined(__mips__)struct mips_hi16{  struct mips_hi16 *next;  Elf32_Addr *addr;  Elf32_Addr value;};#endifstruct arch_file {	struct obj_file root;#if defined(CONFIG_USE_PLT_ENTRIES)	struct obj_section *plt;#endif#if defined(CONFIG_USE_GOT_ENTRIES)	struct obj_section *got;#endif#if defined(__mips__)	struct mips_hi16 *mips_hi16_list;#endif};struct arch_symbol {	struct obj_symbol root;#if defined(CONFIG_USE_PLT_ENTRIES)#if defined(CONFIG_USE_PLT_LIST)	struct arch_list_entry *pltent;#else	struct arch_single_entry pltent;#endif#endif#if defined(CONFIG_USE_GOT_ENTRIES)	struct arch_single_entry gotent;#endif};struct external_module {	const char *name;	ElfW(Addr) addr;	int used;	size_t nsyms;	struct new_module_symbol *syms;};static struct new_module_symbol *ksyms;static size_t nksyms;static struct external_module *ext_modules;static int n_ext_modules;static int n_ext_modules_used;extern int delete_module(const char *);static char *m_filename;static char m_fullName[FILENAME_MAX];/*======================================================================*/static int check_module_name_match(const char *filename, struct stat *statbuf,						   void *userdata){	char *fullname = (char *) userdata;	if (fullname[0] == '\0')		return (FALSE);	else {		char *tmp, *tmp1 = xstrdup(filename);		tmp = get_last_path_component(tmp1);		if (strcmp(tmp, fullname) == 0) {			free(tmp1);			/* Stop searching if we find a match */			m_filename = xstrdup(filename);			return (TRUE);		}		free(tmp1);	}	return (FALSE);}/*======================================================================*/static struct obj_file *arch_new_file(void){	struct arch_file *f;	f = xmalloc(sizeof(*f));	memset(f, 0, sizeof(*f));	return &f->root;}static struct obj_section *arch_new_section(void){	return xmalloc(sizeof(struct obj_section));}static struct obj_symbol *arch_new_symbol(void){	struct arch_symbol *sym;	sym = xmalloc(sizeof(*sym));	memset(sym, 0, sizeof(*sym));	return &sym->root;}static enum obj_relocarch_apply_relocation(struct obj_file *f,					  struct obj_section *targsec,					  struct obj_section *symsec,					  struct obj_symbol *sym,				      ElfW(RelM) *rel, ElfW(Addr) v){	struct arch_file *ifile = (struct arch_file *) f;	enum obj_reloc ret = obj_reloc_ok;	ElfW(Addr) *loc = (ElfW(Addr) *) (targsec->contents + rel->r_offset);	ElfW(Addr) dot = targsec->header.sh_addr + rel->r_offset;#if defined(CONFIG_USE_GOT_ENTRIES) || defined(CONFIG_USE_PLT_ENTRIES)	struct arch_symbol *isym = (struct arch_symbol *) sym;#endif#if defined(CONFIG_USE_GOT_ENTRIES)	ElfW(Addr) got = ifile->got ? ifile->got->header.sh_addr : 0;#endif#if defined(CONFIG_USE_PLT_ENTRIES)	ElfW(Addr) plt = ifile->plt ? ifile->plt->header.sh_addr : 0;	unsigned long *ip;#if defined(CONFIG_USE_PLT_LIST)	struct arch_list_entry *pe;#else	struct arch_single_entry *pe;#endif#endif	switch (ELF32_R_TYPE(rel->r_info)) {#if defined(__arm__)	case R_ARM_NONE:		break;	case R_ARM_ABS32:		*loc += v;		break;			case R_ARM_GOT32:		goto bb_use_got;	case R_ARM_GOTPC:		/* relative reloc, always to _GLOBAL_OFFSET_TABLE_ 		 * (which is .got) similar to branch, 		 * but is full 32 bits relative */		assert(got);		*loc += got - dot;		break;	case R_ARM_PC24:	case R_ARM_PLT32:		goto bb_use_plt;	case R_ARM_GOTOFF: /* address relative to the got */		assert(got);		*loc += v - got;		break;#elif defined(__i386__)	case R_386_NONE:		break;	case R_386_32:		*loc += v;		break;	case R_386_PLT32:	case R_386_PC32:		*loc += v - dot;		break;	case R_386_GLOB_DAT:	case R_386_JMP_SLOT:		*loc = v;		break;	case R_386_RELATIVE:		*loc += f->baseaddr;		break;	case R_386_GOTPC:		assert(got != 0);		*loc += got - dot;		break;	case R_386_GOT32:		goto bb_use_got;	case R_386_GOTOFF:		assert(got != 0);		*loc += v - got;		break;#elif defined(__mc68000__)	case R_68K_NONE:		break;	case R_68K_32:		*loc += v;		break;	case R_68K_8:		if (v > 0xff) {			ret = obj_reloc_overflow;		}		*(char *)loc = v;		break;	case R_68K_16:		if (v > 0xffff) {			ret = obj_reloc_overflow;		}		*(short *)loc = v;		break;	case R_68K_PC8:		v -= dot;		if ((Elf32_Sword)v > 0x7f || 		    (Elf32_Sword)v < -(Elf32_Sword)0x80) {			ret = obj_reloc_overflow;		}		*(char *)loc = v;		break;	case R_68K_PC16:		v -= dot;		if ((Elf32_Sword)v > 0x7fff || 		    (Elf32_Sword)v < -(Elf32_Sword)0x8000) {			ret = obj_reloc_overflow;		}		*(short *)loc = v;		break;	case R_68K_PC32:		*(int *)loc = v - dot;		break;	case R_68K_GLOB_DAT:	case R_68K_JMP_SLOT:		*loc = v;		break;	case R_68K_RELATIVE:		*(int *)loc += f->baseaddr;		break;	case R_68K_GOT32:		goto bb_use_got;	case R_68K_GOTOFF:		assert(got != 0);		*loc += v - got;		break;#elif defined(__mips__)	case R_MIPS_NONE:		break;	case R_MIPS_32:		*loc += v;		break;	case R_MIPS_26:		if (v % 4)			ret = obj_reloc_dangerous;		if ((v & 0xf0000000) != ((dot + 4) & 0xf0000000))			ret = obj_reloc_overflow;		*loc =		    (*loc & ~0x03ffffff) | ((*loc + (v >> 2)) &					    0x03ffffff);		break;	case R_MIPS_HI16:		{			struct mips_hi16 *n;			/* We cannot relocate this one now because we don't know the value			   of the carry we need to add.  Save the information, and let LO16			   do the actual relocation.  */			n = (struct mips_hi16 *) xmalloc(sizeof *n);			n->addr = loc;			n->value = v;			n->next = ifile->mips_hi16_list;			ifile->mips_hi16_list = n;	       		break;		}	case R_MIPS_LO16:		{			unsigned long insnlo = *loc;			Elf32_Addr val, vallo;			/* Sign extend the addend we extract from the lo insn.  */			vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000;			if (ifile->mips_hi16_list != NULL) {				struct mips_hi16 *l;				l = ifile->mips_hi16_list;				while (l != NULL) {					struct mips_hi16 *next;					unsigned long insn;					/* The value for the HI16 had best be the same. */					assert(v == l->value);					/* Do the HI16 relocation.  Note that we actually don't					   need to know anything about the LO16 itself, except where					   to find the low 16 bits of the addend needed by the LO16.  */					insn = *l->addr;					val =					    ((insn & 0xffff) << 16) +					    vallo;					val += v;					/* Account for the sign extension that will happen in the					   low bits.  */					val =					    ((val >> 16) +					     ((val & 0x8000) !=					      0)) & 0xffff;					insn = (insn & ~0xffff) | val;					*l->addr = insn;					next = l->next;					free(l);					l = next;				}				ifile->mips_hi16_list = NULL;			}			/* Ok, we're done with the HI16 relocs.  Now deal with the LO16.  */			val = v + vallo;			insnlo = (insnlo & ~0xffff) | (val & 0xffff);			*loc = insnlo;			break;		}#elif defined(__powerpc__)	case R_PPC_ADDR16_HA:		*(unsigned short *)loc = (v + 0x8000) >> 16;		break;	case R_PPC_ADDR16_HI:		*(unsigned short *)loc = v >> 16;		break;	case R_PPC_ADDR16_LO:		*(unsigned short *)loc = v;		break;	case R_PPC_REL24:		goto bb_use_plt;	case R_PPC_REL32:		*loc = v - dot;		break;	case R_PPC_ADDR32:		*loc = v;		break;#elif defined(__sh__)	case R_SH_NONE:		break;	case R_SH_DIR32:		*loc += v;		break;	case R_SH_REL32:		*loc += v - dot;		break;			case R_SH_PLT32:		*loc = v - dot;		break;	case R_SH_GLOB_DAT:	case R_SH_JMP_SLOT:		*loc = v;		break;	case R_SH_RELATIVE:		*loc = f->baseaddr + rel->r_addend;		break;	case R_SH_GOTPC:		assert(got != 0);		*loc = got - dot + rel->r_addend;		break;	case R_SH_GOT32:		goto bb_use_got;

⌨️ 快捷键说明

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