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

📄 elfinterp.c

📁 它通过提供glibc兼容使得应用程序移植到较小的c 库时相当得容易. 它能够应用到带虚拟存储的Linux和uClinux上.在大多数带MMU部件的平台上为使它更加紧凑,它也能够编译成共享库.uClib
💻 C
📖 第 1 页 / 共 2 页
字号:
		PPC_SYNC;		PPC_ICBI(reloc_addr);	};}int _dl_parse_relocation_information(struct elf_resolve *tpnt, 	unsigned long rel_addr, unsigned long rel_size, int type){	int i;	char *strtab;	int reloc_type;	int goof = 0;	Elf32_Sym *symtab;	ELF_RELOC *rpnt;	unsigned long *reloc_addr;	unsigned long symbol_addr;	int symtab_index;	unsigned long addend;	unsigned long *plt;	DPRINTF("_dl_parse_relocation_information(tpnt=%x, rel_addr=%x, rel_size=%x, type=%d)\n",		tpnt,rel_addr,rel_size,type);	/* Now parse the relocation information */	rpnt = (ELF_RELOC *) (rel_addr + tpnt->loadaddr);	rel_size = rel_size / sizeof(ELF_RELOC);	symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);	strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);	plt = (unsigned long *)(tpnt->dynamic_info[DT_PLTGOT] + tpnt->loadaddr);	for (i = 0; i < rel_size; i++, rpnt++) {		debug_reloc(rpnt);		reloc_addr = (unsigned long *) (tpnt->loadaddr + (unsigned long) rpnt->r_offset);		reloc_type = ELF32_R_TYPE(rpnt->r_info);		symtab_index = ELF32_R_SYM(rpnt->r_info);		addend = rpnt->r_addend;		symbol_addr = 0;		if (!symtab_index && tpnt->libtype == program_interpreter)			continue;		if (symtab_index) {			if (tpnt->libtype == program_interpreter &&				_dl_symbol(strtab + symtab[symtab_index].st_name))				continue;			symbol_addr = (unsigned long) _dl_find_hash(strtab + symtab[symtab_index].st_name, 					tpnt->symbol_scope,					(reloc_type == R_PPC_JMP_SLOT ? tpnt : NULL), symbolrel);			/*			 * We want to allow undefined references to weak symbols - this might			 * have been intentional.  We should not be linking local symbols			 * here, so all bases should be covered.			 */			if (!symbol_addr &&				ELF32_ST_BIND(symtab[symtab_index].st_info) == STB_GLOBAL) {				_dl_dprintf(2, "%s: can't resolve symbol '%s'\n", 					_dl_progname, strtab + symtab[symtab_index].st_name);				goof++;			}		}		debug_sym(symtab,strtab,symtab_index);		switch (reloc_type) {		case R_PPC_NONE:			break;		case R_PPC_REL24:#if 0			{			int delta = symbol_addr - (unsigned long)reloc_addr;			if(delta<<6>>6 != delta){				_dl_dprintf(2,"R_PPC_REL24: Reloc out of range\n");				_dl_exit(1);			}			*reloc_addr &= 0xfc000003;			*reloc_addr |= delta&0x03fffffc;			}			break;#else			_dl_dprintf(2, "%s: symbol '%s' is type R_PPC_REL24\n\tCompile shared libraries with -fPIC!\n",					_dl_progname, strtab + symtab[symtab_index].st_name);			_dl_exit(1);#endif		case R_PPC_RELATIVE:			*reloc_addr = (unsigned long)tpnt->loadaddr + addend;			break;		case R_PPC_ADDR32:			*reloc_addr += symbol_addr;			break;		case R_PPC_ADDR16_HA:			/* XXX is this correct? */			*(short *)reloc_addr += (symbol_addr+0x8000)>>16;			break;		case R_PPC_ADDR16_HI:			*(short *)reloc_addr += symbol_addr>>16;			break;		case R_PPC_ADDR16_LO:			*(short *)reloc_addr += symbol_addr;			break;		case R_PPC_JMP_SLOT:			{			unsigned long targ_addr = (unsigned long)*reloc_addr;			int delta = targ_addr - (unsigned long)reloc_addr;			if(delta<<6>>6 == delta){				*reloc_addr = OPCODE_B(delta);			}else if (targ_addr <= 0x01fffffc || targ_addr >= 0xfe000000){				*reloc_addr = OPCODE_BA (targ_addr);			}else{	{	int delta;	int index;		delta = (unsigned long)(plt+PLT_TRAMPOLINE_ENTRY_WORDS+2)		- (unsigned long)(reloc_addr+1);	index = ((unsigned long)reloc_addr -		(unsigned long)(plt+PLT_INITIAL_ENTRY_WORDS))		/sizeof(unsigned long);	index /= 2;	DPRINTF("        index %x delta %x\n",index,delta);	reloc_addr[0] = OPCODE_LI(11,index*4);	reloc_addr[1] = OPCODE_B(delta);	}			}			break;			}		case R_PPC_GLOB_DAT:			*reloc_addr += symbol_addr;			break;		case R_PPC_COPY:			// handled later			break;		default:			_dl_dprintf(2, "%s: can't handle reloc type ", _dl_progname);#if defined (__SUPPORT_LD_DEBUG__)			_dl_dprintf(2, "%s ", _dl_reltypes[reloc_type]);#endif			if (symtab_index)				_dl_dprintf(2, "'%s'\n", strtab + symtab[symtab_index].st_name);			_dl_exit(1);		};		/* instructions were modified */		PPC_DCBST(reloc_addr);		PPC_SYNC;		PPC_ICBI(reloc_addr);		DPRINTF("reloc_addr %x: %x\n",reloc_addr,*reloc_addr);	};	return goof;}/* This is done as a separate step, because there are cases where   information is first copied and later initialized.  This results in   the wrong information being copied.  Someone at Sun was complaining about   a bug in the handling of _COPY by SVr4, and this may in fact be what he   was talking about.  Sigh. *//* No, there are cases where the SVr4 linker fails to emit COPY relocs   at all */int _dl_parse_copy_information(struct dyn_elf *xpnt, unsigned long rel_addr, 	unsigned long rel_size, int type){	int i;	char *strtab;	int reloc_type;	int goof = 0;	Elf32_Sym *symtab;	ELF_RELOC *rpnt;	unsigned long *reloc_addr;	unsigned long symbol_addr;	struct elf_resolve *tpnt;	int symtab_index;	DPRINTF("parse_copy xpnt=%x rel_addr=%x rel_size=%x type=%d\n",		(int)xpnt,rel_addr,rel_size,type);	/* Now parse the relocation information */	tpnt = xpnt->dyn;	rpnt = (ELF_RELOC *) (rel_addr + tpnt->loadaddr);	rel_size = rel_size / sizeof(ELF_RELOC);	symtab = (Elf32_Sym *) (tpnt->dynamic_info[DT_SYMTAB] + tpnt->loadaddr);	strtab = (char *) (tpnt->dynamic_info[DT_STRTAB] + tpnt->loadaddr);	for (i = 0; i < rel_size; i++, rpnt++) {		reloc_addr = (unsigned long *) (tpnt->loadaddr + (unsigned long) rpnt->r_offset);		reloc_type = ELF32_R_TYPE(rpnt->r_info);		if (reloc_type != R_PPC_COPY)			continue;		debug_reloc(rpnt);		symtab_index = ELF32_R_SYM(rpnt->r_info);		symbol_addr = 0;		if (!symtab_index && tpnt->libtype == program_interpreter)			continue;		if (symtab_index) {			if (tpnt->libtype == program_interpreter &&				_dl_symbol(strtab + symtab[symtab_index].st_name))				continue;			symbol_addr = (unsigned long) _dl_find_hash(strtab + 				symtab[symtab_index].st_name, xpnt->next, 				NULL, copyrel);			if (!symbol_addr) {				_dl_dprintf(2, "%s: can't resolve symbol '%s'\n", 					_dl_progname, strtab + symtab[symtab_index].st_name);				goof++;			};		};		debug_sym(symtab,strtab,symtab_index);		DPRINTF("copy: to=%x from=%x size=%x\n",			symtab[symtab_index].st_value, 			symbol_addr, symtab[symtab_index].st_size);		if (!goof) {			_dl_memcpy((char *) symtab[symtab_index].st_value, 				(char *) symbol_addr,				symtab[symtab_index].st_size);		}	};	return goof;}#ifdef unusedstatic void fixup_jmpslot(unsigned long reloc_addr, unsigned long targ_addr){	int delta = targ_addr - reloc_addr;	int index;		if(delta<<6>>6 == delta){		*reloc_addr = OPCODE_B(delta);	}else if (targ_addr <= 0x01fffffc || targ_addr >= 0xfe000000){		*reloc_addr = OPCODE_BA (targ_addr);	}else{		delta = (unsigned long)(plt+PLT_TRAMPOLINE_ENTRY_WORDS+2)			- (unsigned long)(reloc_addr+1);		index = ((unsigned long)reloc_addr -			(unsigned long)(plt+PLT_INITIAL_ENTRY_WORDS))			/sizeof(unsigned long);		index /= 2;		DPRINTF("        index %x delta %x\n",index,delta);		reloc_addr[0] = OPCODE_LI(11,index*4);		reloc_addr[1] = OPCODE_B(delta);	}}#endif#ifdef __SUPPORT_LD_DEBUG__static void debug_sym(Elf32_Sym *symtab,char *strtab,int symtab_index){	if (_dl_debug_symbols) {		if(symtab_index){			_dl_dprintf(2, "sym: name=%s value=%x size=%x info=%x other=%x shndx=%x\n",					strtab + symtab[symtab_index].st_name,					symtab[symtab_index].st_value,					symtab[symtab_index].st_size,					symtab[symtab_index].st_info,					symtab[symtab_index].st_other,					symtab[symtab_index].st_shndx);		}else{			_dl_dprintf(2, "sym: null\n");		}	}}static void debug_reloc(ELF_RELOC *rpnt){	if (_dl_debug_reloc) {		_dl_dprintf(2, "reloc: offset=%x type=%x sym=%x addend=%x\n",				rpnt->r_offset,				ELF32_R_TYPE(rpnt->r_info),				ELF32_R_SYM(rpnt->r_info),				rpnt->r_addend);	}}#endif

⌨️ 快捷键说明

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